diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/blooddy_crypto/LICENSE.md b/blooddy_crypto/LICENSE.md new file mode 100755 index 0000000..00ad983 --- /dev/null +++ b/blooddy_crypto/LICENSE.md @@ -0,0 +1,24 @@ +MIT License +=========== + +Copyright (C) 2010 Nick Ryzhy / blooddy@tut.by / www.blooddy.by + +----------- +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +----------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/blooddy_crypto/LICENSE.md b/blooddy_crypto/LICENSE.md new file mode 100755 index 0000000..00ad983 --- /dev/null +++ b/blooddy_crypto/LICENSE.md @@ -0,0 +1,24 @@ +MIT License +=========== + +Copyright (C) 2010 Nick Ryzhy / blooddy@tut.by / www.blooddy.by + +----------- +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +----------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/blooddy_crypto/blooddy_crypto.swc b/blooddy_crypto/blooddy_crypto.swc new file mode 100755 index 0000000..ba33cc4 --- /dev/null +++ b/blooddy_crypto/blooddy_crypto.swc Binary files differ diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/blooddy_crypto/LICENSE.md b/blooddy_crypto/LICENSE.md new file mode 100755 index 0000000..00ad983 --- /dev/null +++ b/blooddy_crypto/LICENSE.md @@ -0,0 +1,24 @@ +MIT License +=========== + +Copyright (C) 2010 Nick Ryzhy / blooddy@tut.by / www.blooddy.by + +----------- +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +----------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/blooddy_crypto/blooddy_crypto.swc b/blooddy_crypto/blooddy_crypto.swc new file mode 100755 index 0000000..ba33cc4 --- /dev/null +++ b/blooddy_crypto/blooddy_crypto.swc Binary files differ diff --git a/exporter.py b/exporter.py index 027380d..e20dbc6 100755 --- a/exporter.py +++ b/exporter.py @@ -109,7 +109,6 @@ def handle_command(msg_str): # return False to quit the driver loop msg = json.loads(msg_str) - print msg if "command" in msg: cmd = msg["command"] if cmd == "exit": diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/blooddy_crypto/LICENSE.md b/blooddy_crypto/LICENSE.md new file mode 100755 index 0000000..00ad983 --- /dev/null +++ b/blooddy_crypto/LICENSE.md @@ -0,0 +1,24 @@ +MIT License +=========== + +Copyright (C) 2010 Nick Ryzhy / blooddy@tut.by / www.blooddy.by + +----------- +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +----------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/blooddy_crypto/blooddy_crypto.swc b/blooddy_crypto/blooddy_crypto.swc new file mode 100755 index 0000000..ba33cc4 --- /dev/null +++ b/blooddy_crypto/blooddy_crypto.swc Binary files differ diff --git a/exporter.py b/exporter.py index 027380d..e20dbc6 100755 --- a/exporter.py +++ b/exporter.py @@ -109,7 +109,6 @@ def handle_command(msg_str): # return False to quit the driver loop msg = json.loads(msg_str) - print msg if "command" in msg: cmd = msg["command"] if cmd == "exit": diff --git a/job.py b/job.py index d100368..d4e73e8 100644 --- a/job.py +++ b/job.py @@ -1,4 +1,5 @@ import os.path +import base64 from args import * class Job: @@ -9,10 +10,16 @@ self.id = Job.next_id Job.next_id += 1 self.input = abspath(input) - self.base = base if base is not None else os.path.split(input)[0] + split = os.path.split(input) + self.base = base if base is not None else split[0] if not file_in_path(self.input, self.base): raise Exception("Failed: " + input + " is not in base dir " + self.base) self.type = type self.scale = scale + self.name = os.path.splitext(split[1])[0] + self.done = False def get_cmd(self): - return {"type":self.type, "scale":self.scale, "id":self.id} + with open(self.input, mode="rb") as f: + contents = f.read() + + return {"type":self.type, "scale":self.scale, "id":self.id, "name":self.name, "input":base64.b64encode(contents)} diff --git a/Exporter.as b/Exporter.as index c520e93..45552d3 100644 --- a/Exporter.as +++ b/Exporter.as @@ -6,6 +6,8 @@ import flash.desktop.*; import flash.errors.*; import flash.system.*; + import flash.utils.*; + import by.blooddy.crypto.*; public class Exporter extends MovieClip { @@ -84,11 +86,43 @@ private var activeJob:Job = null; private function QueueJob(jobParams) { - var job:Job = new Job(jobParams); + var input:ByteArray = null; + if (jobParams.hasOwnProperty("input")) + { + input = Base64.decode("" + jobParams.input); + } + + if (!jobParams.hasOwnProperty("id")) + { + Print("Failure: job details didn't contain job id"); + CheckNewJob(); + return; + } + var id:int = parseInt(jobParams.id); + + if (!jobParams.hasOwnProperty("name")) + { + Print("Failure: job " + id + " details didn't contain job name"); + JobFailed(id); + return; + } + var name:String = "" + jobParams.name; + + delete jobParams.command; + delete jobParams.input; + delete jobParams.id; + + var job:Job = new Job(id, name, input, jobParams); jobQueue.push(job); CheckNewJob(); } + private function JobFailed(id:int) + { + DriverCommand("done", {id:id}); + CheckNewJob(); + } + private function CheckNewJob() { if (activeJob == null && jobQueue.length > 0) @@ -111,11 +145,10 @@ { try { - Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command")); if (cmdData.hasOwnProperty("command")) { var cmd = "" + cmdData.command; - Trace("cmd: " + cmd); + //Trace("cmd: " + cmd); switch (cmd) { case "trace": @@ -128,32 +161,42 @@ QueueJob(cmdData); break; default: - Trace("Recv: " + JSON.stringify(cmdData)); + Trace("Recv unknown: " + JSON.stringify(cmdData)); break; } } } catch (e) { - Print(e.toString()); + Print(e.getStackTrace()); } } + private var buffer:ByteArray = new ByteArray(); + private var swpBuffer:ByteArray = new ByteArray(); private function DriverRecv(e) { - Trace("recv"); + var oldPos = buffer.position; + //Trace("recv"); try { - Trace(e.target.bytesAvailable); - var msg = driver.readUTF(); - Trace("msg: " + msg); - Trace("avail: " + e.target.bytesAvailable); + driver.readBytes(buffer, buffer.length, driver.bytesAvailable); + //Trace(buffer.length - buffer.position); + var msg = buffer.readUTF(); + + buffer.readBytes(swpBuffer); + buffer.clear(); + + var tmp = buffer; + buffer = swpBuffer; + swpBuffer = tmp; + var cmdData = JSON.parse(msg); - Trace("cmdData: " + cmdData + " " + typeof(cmdData)); DispatchCommand(cmdData); } catch (eof:EOFError) { - Trace("Waiting for more data... " + e.target.bytesAvailable); + buffer.position = oldPos; + //Trace("Waiting for more data... " + driver.bytesAvailable + " " + (buffer.length - buffer.position)); // wait for more data } catch (err:IOError) @@ -162,7 +205,7 @@ } catch (err) { - Trace("Problem reading from driver"); + Trace("Problem reading from driver:\n" + err.toString()); } } @@ -189,8 +232,9 @@ } } - public function Trace(str:String) + public function Trace(str) { + str = "" + str; traceText.x = 2; trace(str); @@ -219,7 +263,7 @@ } if (driver != null) { - DriverCommand("print", {string:str}); + DriverCommand("print", {string:str + "\n"}); } } } diff --git a/Exporter.exe b/Exporter.exe index 745928e..aa5d57e 100755 --- a/Exporter.exe +++ b/Exporter.exe Binary files differ diff --git a/Exporter.fla b/Exporter.fla index a0f0ea8..83dfa3e 100755 --- a/Exporter.fla +++ b/Exporter.fla Binary files differ diff --git a/Exporter.swf b/Exporter.swf index df8c3fb..484f56c 100644 --- a/Exporter.swf +++ b/Exporter.swf Binary files differ diff --git a/Job.as b/Job.as index 859be61..27c78fb 100755 --- a/Job.as +++ b/Job.as @@ -1,22 +1,76 @@ package { import flash.utils.*; + import flash.display.*; + import flash.system.LoaderContext; + import flash.events.*; + public class Job { private var callback; private var id:int; + private var name:String; + private var input:ByteArray; + private var details; + private var inputLoader:Loader = null; public function GetID():int { return this.id; } - public function Job(details) + public function Job(id:int, name:String, input:ByteArray, details) { - id = parseInt(details["id"]); + this.id = id; + this.name = name; + this.input = input; + this.details = details; Exporter.Instance.Trace("new job: " + id); } + private function Fail(err:String) + { + Exporter.Instance.Print("Failure: job " + id + ": " + err); + callback(); + } public function Go(callback) { - Exporter.Instance.Trace("Job.Go() " + id); this.callback = callback; - setTimeout(Done, 500); + + if (this.input == null) + { + Fail("contained no input"); + return; + } + + inputLoader = new Loader(); + inputLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete); + inputLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError); + inputLoader.loadBytes(input, new LoaderContext()); + } + private function LoaderComplete(e) + { + try + { + var classDef = e.target.applicationDomain.getDefinition(name); + if (classDef == null) + { + Fail("didn't contain a definition for " + name); + return; + } + + var clip = new classDef(); + if (!(clip is MovieClip)) + { + Fail(name + " wasn't a movieclip"); + } + + Utils.RecursivelyStop(clip); + + Done(); + } catch (e) + { + Exporter.Instance.Print(e.getStackTrace()); + } + } + private function LoaderError(e) + { + Fail("couldn't load input: " + e.toString()); } public function Done() { diff --git a/Utils.as b/Utils.as index b24dd91..83c797c 100644 --- a/Utils.as +++ b/Utils.as @@ -1,243 +1,13 @@ package { - /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of - * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! - */ - import flash.utils.*; - import flash.net.*; import flash.display.*; - import flash.text.TextField; - import flash.text.TextFormat; - import flash.text.TextFieldType; - import flash.text.TextFieldAutoSize; - import flash.text.TextFormatAlign; - import flash.geom.Point; - import flash.geom.Matrix; - import flash.geom.Rectangle; - import flash.geom.ColorTransform; - import fl.motion.Color; - import fl.transitions.Tween; - import fl.transitions.easing.*; - import fl.transitions.TweenEvent; - import flash.net.navigateToURL; - import flash.external.ExternalInterface; - import flash.system.Capabilities; - import flash.filters.*; - import flash.filters.ColorMatrixFilter; - import com.adobe.images.JPGEncoder; - import flash.globalization.DateTimeFormatter; - - import djarts.utils.Base64; - import djarts.utils.PNGEnc; - import User.UserOptions; - - public class Utils + public class Utils { - //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] - static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; - static var divisors = []; - - public static function FormatBigNumber(number:*, round:Boolean=false):String - { - if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); - - var isWholeNumber = (Math.floor(number) == number); - round = round || isWholeNumber; - - if (number < 1000) - { - if (round) - { - return Math.round(number).toString(); - } - else - { - var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. - var roundMult = Math.pow(10, decimalPlaces); - var rounded = Math.round(number); - var bigRounded = Math.round(number * roundMult); - var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; - - if (roundedDifferenceProportion < 0.001) - { - // Not a whole number, but the decimal places aren't worth showing - // Below also handles this, but is slower - return rounded.toString(); - } - else - { - var str:String = bigRounded.toString(); - str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); - - while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once - if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all - - return str; - } - } - } - - // Determine which symbol to use - var power = Math.floor(Math.log(number) / Math.log(1000)); - var index = Math.min(power-1, symbols.length-1); - var amount = number / Math.pow(1000, index+1); - var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; - - // If it's too big for a symbol (or if we just WANT to) - if (amount >= 1000 || UserOptions.ForceScientific) - { - // scientific notation - var power = Math.floor(Math.log(number) / Math.log(10)); - var num = number / Math.pow(10, power); - if (num == 10) { - num = 1; - power += 1; - } - var numString = "" + num; - numString = numString.substr(0, Math.min(4, numString.length)); - return numString + "e" + power; - - } - else - { - // Format with the symbol - // determine number of whole digits (will dictate how many decimals we show) - var whole = Math.floor(amount); - var amount_str:String = String(whole); - - var decimalDivider = 100/Math.pow(10,amount_str.length-1); - - //round to nearest decimal place - amount = int(amount*decimalDivider)/decimalDivider; - - var amountString:String = amount.toString(); - - var noDecimal:String = amountString.replace(".",""); - if (noDecimal.length == 2) - { - if (amountString.indexOf(".") != -1) amountString += "0"; - else amountString += ".0"; - } - else if (noDecimal.length == 1) amountString += ".00"; - - return amountString+symbol; // concat symbol - } - } - - private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); - // Note-DG: This is mostly just used for definitions in the database, that don't require precision. - // This way we can define values in the database as 100B instead of 100000000000. - public static function ParseBigNumberString(number:String):Number - { - var regexArray:Array = BigNumberRegex.exec(number); - var magnitude = symbols.indexOf(regexArray[3]); - var thousands:Number; - if (regexArray[1]) { - thousands = regexArray[1]; - if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 - thousands *= 1000; - } - } else { - thousands = 0; - } - var hundreds:Number = regexArray[2] ? regexArray[2] : 0; - - return (thousands + hundreds) * Math.pow(1000, magnitude + 1); - } - - public static function ParseNumberRange(range:String):Array - { - var split:Array = range.split(','); - return [Number(split[0]), Number(split[1])]; - } - - public static function DesaturateFilter() - { - var desatMatrix:Array = []; - var cmFilter; - - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green - desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue - desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha - cmFilter = new ColorMatrixFilter(desatMatrix); - - return cmFilter; - } - - public static function GetUserAgent():String - { - try - { - var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); - var browser:String = "[Unknown Browser]"; - - if (userAgent.indexOf("Safari") != -1) - { - browser = "Safari"; - } - if (userAgent.indexOf("Firefox") != -1) - { - browser = "Firefox"; - } - if (userAgent.indexOf("Chrome") != -1) - { - browser = "Chrome"; - } - if (userAgent.indexOf("MSIE") != -1) - { - browser = "Internet Explorer"; - } - if (userAgent.indexOf("Opera") != -1) - { - browser = "Opera"; - } - } - catch (e:Error) - { - //could not access ExternalInterface in containing page - return "[No ExternalInterface]"; - } - - return browser; - } - - public static function GetScreenshot(stage:Stage):String { - var scale:Number = 0.25; - var result:String = null; - var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); - - var bData:BitmapData = new BitmapData(stage.stageWidth * scale, - stage.stageHeight * scale, false, 0x348400); - var matrix:Matrix = new Matrix(); - matrix.scale(scale, scale); - - bData.draw(stage, matrix); - bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); - - - var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); - //var imgBytes:ByteArray = PNGEnc.encode(bData); - if (imgBytes) { - var screenshotBase64:String = Base64.encode(imgBytes); - if (screenshotBase64) { - result = screenshotBase64; - } - } - - return result; - } - - public static function RecursivelyStop(clip, frame = null) + public static function RecursivelyStop(clip) { if (clip is MovieClip) { - if (frame == null) - { - clip.stop(); - } else { - clip.gotoAndStop(frame); - } + clip.stop(); } if (clip is DisplayObjectContainer) { @@ -247,956 +17,5 @@ } } } - - public static function PlayerVersion() - { - - // Get the player's version by using the getVersion() global function. - var versionNumber:String = Capabilities.version; - - // The version number is a list of items divided by "," - var versionArray:Array = versionNumber.split(","); - var length:Number = versionArray.length; - //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); - - // The main version contains the OS type too so we split it in two - // and we'll have the OS type and the major version number separately. - var platformAndVersion:Array = versionArray[0].split(" "); - //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); - //_strace("-----"); - - var majorVersion:Number = parseInt(platformAndVersion[1]); - var minorVersion:Number = parseInt(versionArray[1]); - var buildNumber:Number = parseInt(versionArray[2]); - - return Number(majorVersion+"."+minorVersion); - } - - - public static function OpenLocalURLTop(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); - } - - public static function OpenLocalURL(url) - { - navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); - } - - public static function OpenURL(url, window = "_blank") - { - navigateToURL(new URLRequest(url), window); - } - - public static var ExitFullScreenCallback; - - public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) - { - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); - ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); - - //if (Settings.Platform == Settings.HI5) { - //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); - //} - } - - public static function SendToRecipients(recipients:Array, description, data) - { - if (!GameSettings.IsFacebook) return; - - if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); - try { - ExternalInterface.call("sendToRecipients", recipients, description ,data); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function GetFriendData() - { - try { - return ExternalInterface.call("pollInviteData"); - } - catch (e) - { - _strace(e.message); - } - } - - - public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number - { - t = t / d; - if (t < 0.7) { - t *= 1.0 / 0.65; - return c * (t * t) + b; - } - return c * (t * t) + b; - } - - public static function Finish(e:TweenEvent) - { - //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); - e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); - } - public static function Popup(mc, startScale = 0.8, finishCallback = null) - { - var rect:Rectangle = mc.getRect(mc); - var targetX = mc.x; - var targetY = mc.y; - var centerX = mc.x + rect.left + mc.width / 2.0; - var centerY = mc.y + rect.top + mc.height / 2.0; - var startX = centerX - (rect.left + mc.width / 2.0) * startScale; - var startY = centerY - (rect.top + mc.height / 2.0) * startScale; - var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); - if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); - if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); - if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); - return [tweenSX, tweenSY, tweenX, tweenY]; - } - public static function StringSplit(s:String, delim:String, max:int = -1):Array - { - var ret:Array = s.split(delim); - if (max != -1) { - var more:String = ret.slice(max - 1).join(delim); - ret.splice(max - 1); - ret[max - 1] = more; - } - return ret; - } - - public static function StringStartsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(0, substr.length) == substr); - } - - public static function StringEndsWith(str:String, substr:String):Boolean - { - if (substr.length > str.length) return false; - return (str.substr(str.length - substr.length, substr.length) == substr); - } - - public static function StringContains(str:String, substr:String):Boolean - { - return (str.indexOf(substr) !== -1); - } - - private static var vowelsAndH = { - "a":true, "A":true, - "e":true, "E":true, - "i":true, "I":true, - "o":true, "O":true, - "u":true, "U":true, - "h":true, "H":true - } - public static function StringStartsWithVowelOrH(s:String):Boolean - { - if (vowelsAndH[s.charAt(0)]) return true; - return false; - } - - public static function CopyObject(obj, except = null) - { - var i; - if (except == null) except = []; - if (obj is Array) { - var obj2 = []; - for (i = 0; i < obj.length; i++) { - obj2.push(Utils.CopyObject(obj[i])); - } - return obj2; - } - var ret:Object = {}; - for (i in obj) - { - if (except.indexOf(i) == -1) { - ret[i] = obj[i]; - } - } - - return ret; - } - public static function CopyToObject(objFrom, objTo, except = null) - { - if (except == null) except = []; - for (var i in objFrom) - { - if (except.indexOf(i) == -1) { - objTo[i] = objFrom[i]; - } - } - } - public static function CopyToObjectOnly(objFrom, objTo, only) - { - if (only == null) return; - for (var i in only) - { - if (objFrom.hasOwnProperty(only[i])) - { - objTo[only[i]] = objFrom[only[i]]; - } - } - } - - public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) - { - var cTransform = clip.transform.colorTransform; - cTransform.redOffset = r; - cTransform.greenOffset = g; - cTransform.blueOffset = b; - clip.transform.colorTransform = cTransform; - } - - public static function hex2rgb (hex):Object - { - var red = hex>>16; - var greenBlue = hex-(red<<16) - var green = greenBlue>>8; - var blue = greenBlue - (green << 8); - return({r:red, g:green, b:blue}); - } - - public static function RGBtoHEX(r, g, b) { - return r << 16 | g << 8 | b; - } - - /** - * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) - */ - public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) - { - var cTint:Color = new Color(); - cTint.setTint(color, alpha); - obj.transform.colorTransform = cTint; - } - - // given an origin (ox, oy) and a look at point (tx, ty), - // and a clip with the given number of rotation states, which - // rotation should we pick? - public static function Rotation(ox, oy, tx, ty, rotations) - { - var delta:Point = new Point(tx - ox, ty - oy); - if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { - delta.y = -1.0; - } - var d = ( - (-Math.floor( - /* calculate the rotation and scale it */ - Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations - + 0.5 // add 0.5 and take the floor (round to closest int) - ) - + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, - // we negate it and add rotations again to get it in the range - // [0, rotations] - % rotations) + 1; // add 1 to reference frames - return d; - } - /* performs multiple operations asynchronously, but wait for them all to finish: - * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions - * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks - * this will wait until every command is complete and call all the callbacks at once. - * - * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, - * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate - * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. - * When these 4 calls complete, the provided 4 functions will be called with the arguments returned - * from the callbacks (in this case, only DoneLoading will be called since the - * other callbacks are null). - */ - public static function WaitForFunctions(...funcs):Object - { - var ret:Object = {}; - // has a callback been hit? - ret.hit = new Array(funcs.length); - // what were the original arguments the callback was called with - ret.args = new Array(funcs.length); - // a list of the artifical callbacks we are providing - ret.callbacks = new Array(funcs.length); - // the real callbacks - ret.funcs = funcs; - ret.done = false; - - ret.immediate = []; - - for (var i = 0; i < funcs.length; i++) { - // we have to setup this temp callback in another function, because the anon function's - // activation object will contain the current scope, meaning that the variable - // i will be updated in each function; if we do it in a seperate function each - // activation object will reference a different i - ret.callbacks[i] = Utils.SetupFunction(ret, i); - } - return ret; - } - - /** - * Returns the standard money format for an integer amount - */ - public static function FormatCurrency(amount:int, symbol:String = "$"):String - { - var afterDecimal:String = (amount % 100).toString(); - while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation - - var beforeDecimal:String; - if (amount > 100) - { - beforeDecimal = Math.floor(amount/100).toString(); - } - else - { - beforeDecimal = "0"; - } - - return symbol + beforeDecimal + "." + afterDecimal; - } - - public static function FormatNumber(amount){ - var whole = Math.floor(amount); - // convert the number to a string - var amount_str:String = String(whole); - var total_str:String = String(amount); - - var number_array:Array = []; - var start:Number; - var end:Number = amount_str.length; - while (end > 0) { - start = Math.max(end - 3, 0); - number_array.unshift(amount_str.slice(start, end)); - end = start; - } - - var point = total_str.indexOf("."); - - var ret = number_array.join(","); - if (point != -1 && point < total_str.length) - { - ret += total_str.substr(point); - } - - return ret; - } - - protected static function SetupFunction(ret, i):Function - { - var a:Function = - function(...rest) { - if (ret.immediate[i]) ret.immediate[i].apply(null, rest); - ret.hit[i] = true; - ret.args[i] = rest; - var ok:Boolean = true; - var j; - for (j = 0; j < ret.hit.length; j++) { - if (!ret.hit[j]) { ok = false; break; } - } - if (ok && !ret.done) { - ret.done = true; - for (j = 0; j < ret.funcs.length; j++) { - if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); - } - } - }; - return a; - } - - // useful for the paned dialogs to show a certain pane/button - public static function OnlyVisible(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].visible = false; - } else { - obj[set[i]].visible = true; - } - } - } - public static function AllVisible(obj, set:Array) - { - for (var i in set) { - obj[set[i]].visible = true; - } - } - // set one of a list of tabs to be enabled - public static function OnlyToggled(obj, set:Array, index:int) - { - for (var i in set) { - if (i != index) { - obj[set[i]].SetToggled(false); - } else { - obj[set[i]].SetToggled(true); - } - } - } - // get the frame number of a label in the timeline - public static function GetLabelFrame(mc, name:String):int - { - for (var l in mc.currentLabels) { - if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; - } - return 1; - } - // generate a quick text field of a certain color/style - public static function BasicTextField(color:uint, - size:int, - font:String, - text:String, - additional:Object = null, - align = "left"):TextField - { - var t:TextField = new TextField(); - var f:TextFormat = new TextFormat(); - f.align = align; - if (additional != null) for (var a in additional) f[a] = additional[a]; - f.font = font; - f.color = color; - f.size = size; - t.type = TextFieldType.DYNAMIC; - t.defaultTextFormat = f; - t.text = text; - t.selectable = false; - t.autoSize = TextFieldAutoSize.LEFT; - return t; - } - public static function var_dump(_obj, name = "Dump") - { - _strace(name + " " + (_obj) + " {"); - flash.utils.describeType(_obj); - var varList:XMLList = flash.utils.describeType(_obj)..variable; - - for(var i:int; i < varList.length(); i++) - { - //Show the name and the value - _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); - } - _strace("}"); - } - - public static function SetChildFrames(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - parentClip.gotoAndStop(frame); - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - public static function SetChildFramesNoParent(parentClip, frame, exclude = null) - { - if (parentClip is MovieClip && parentClip.name != exclude) - { - for (var i = 0; i < parentClip.numChildren; i++) - { - Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); - } - } - } - - //modifies the array passed as parameter, following the MO of the built in Array.sort() - public static function insertionSort(array:Array, compareFunction:Function):void - { - for(var i:int=1; i < array.length; i++) - { - var value:Object = array[i]; - var k:int=i-1; - while( k >= 0 && compareFunction(array[k], value) == -1) - { - array[k+1]=array[k]; - k--; - } - array[k+1]=value; - } - } - - - public static function Screenshot(sourceClip, receiverURL, filename) - { - - var jpgSource:BitmapData; - - if (sourceClip is Stage) - { - jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); - } else { - jpgSource = new BitmapData (sourceClip.width, sourceClip.height); - } - - jpgSource.draw(sourceClip); - - var jpgEncoder:JPGEncoder = new JPGEncoder(85); - var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); - - var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); - var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); - jpgURLRequest.requestHeaders.push(header); - jpgURLRequest.method = URLRequestMethod.POST; - jpgURLRequest.data = jpgStream; - navigateToURL(jpgURLRequest, "_blank"); - - } - - - public static function SetColors(clip, color) - { - var colorTransform:ColorTransform; - - if (clip == null || color == null) return; - - if (clip.hasOwnProperty("outline") && clip.outline != null) - { - colorTransform = clip.outline.transform.colorTransform; - colorTransform.color = color.Outline; - clip.outline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) - { - colorTransform = clip.secondaryOutline.transform.colorTransform; - colorTransform.color = color.LightOutline; - clip.secondaryOutline.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("color") && clip.color != null) - { - colorTransform = clip.color.transform.colorTransform; - colorTransform.color = color.Primary; - clip.color.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) - { - colorTransform = clip.secondaryColor.transform.colorTransform; - colorTransform.color = color.Secondary; - clip.secondaryColor.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("shadow") && clip.shadow != null) - { - colorTransform = clip.shadow.transform.colorTransform; - colorTransform.color = color.Shadow; - clip.shadow.transform.colorTransform = colorTransform; - } - - if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) - { - colorTransform = clip.secondaryShadow.transform.colorTransform; - colorTransform.color = color.SecondaryShadow; - clip.secondaryShadow.transform.colorTransform = colorTransform; - } - } - /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ - public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) - { - var rect:Rectangle = new Rectangle(0,0,0,0); - - var widthScale = Math.min(maxWidth / clip.width, 999); - var heightScale = Math.min(maxHeight / clip.height, 999); - - var scale = 1; - if (widthScale > heightScale) - { - scale = heightScale; - } else { - scale = widthScale; - } - - rect.width = clip.width * scale; - rect.height = clip.height * scale; - - var pb = clip.getBounds(clip); - var xadjust = -pb.left * scale; - var yadjust = -pb.top * scale; - - rect.x = xadjust + (maxWidth - rect.width) / 2; - rect.y = yadjust + (maxHeight - rect.height) / 2; - - rect.width = scale; - rect.height = scale; - - return rect; - } - - public static function Dec2Hex(d) - { - var chars:String = "0123456789ABCDEF"; - var str:String = ""; - while (d > 0 || str.length < 2) - { - var digit = d % 16; - d = (d - digit) / 16; - str = chars.charAt(digit) + str; - } - return str; - } - - public static function Hex2Dec(h:String) - { - var chars:String = "0123456789ABCDEF"; - var val = 1; - var res = 0; - for (var i = h.length - 1; i >= 0; i--) - { - res += chars.indexOf(h.substr(i, 1)) * val; - val *= 16; - } - return res; - } - - public static function ShallowCopyArray(array:Array) - { - if (!array) return null; - - var newArray:Array = []; - for (var i:int = 0; i < array.length; i++) - { - newArray.push(array[i]); - } - return newArray; - } - - /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) - * (as opposed to value type semantics) - */ - public static function areEqual(a:Array,b:Array):Boolean { - if(a.length != b.length) { - return false; - } - var len:int = a.length; - for(var i:int = 0; i < len; i++) { - if(a[i] !== b[i]) { - return false; - } - } - return true; - } - - /* Note: Will fail if any items in either array have reference type semantics - * (as opposed to value type semantics) - */ - public static function objectsAreEqual(a:Object,b:Object):Boolean { - - for (var i in a) - { - if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; - } - - return true; - } - - public static function DeepCopyClone (source : Object) : * - { - var array : ByteArray = new ByteArray (); - - array.writeObject (source); - array.position = 0; - - return array.readObject (); - } - - // {a:1, b:2} => [1,2] - public static function ObjectValues (obj:Object):Array { - var array = []; - for (var key in obj) array.push(obj[key]); - return array; - } - - // {a:1, b:2} => ["a","b"] - public static function ObjectKeys (obj:Object):Array { - var array = []; - for (var key in obj) array.push(key); - return array; - } - - // normal random variate generator; mean m, standard deviation s - public static function BoxMullerRandomNormal(m:Number, s:Number) : Number - { - var x1, x2, w, y1:Number; - var y2:Number; - var use_last:Boolean = false; - - if (use_last == true) /* use value from previous call */ - { - y1 = y2; - use_last = false; - } - else - { - do { - x1 = 2.0 * Math.random() - 1.0; - x2 = 2.0 * Math.random() - 1.0; - w = x1 * x1 + x2 * x2; - } while ( w >= 1.0 ); - - w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); - y1 = x1 * w; - y2 = x2 * w; - use_last = true; - } - - return( m + y1 * s ); - } - - public static function SanitizeNumber(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; - } - return n; - } - - public static function IsNumberInvalid(n) - { - if (n is Number) - { - if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; - } - return false; - } - - public static function LimitNumberToMax(n) - { - if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; - return n; - } - - /* - value= Math.round(20/7); - value= int((20/7)*10)/10; - value= int((20/7)*100)/100; - value= int((20/7)*1000)/1000; - value= int((20/7)*10000)/10000; - */ - public static function RoundToDecimalPlaces(number:Number, places:int) - { - return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); - } - - public static function GetShuffledArray(a:Array) : Array - { - var r:Array = a.concat(); - r.sort(randomSort); - return r; - } - - ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) - public static function ShuffleArray(a:Array) - { - a.sort(randomSort); - } - - public static function PickRandom(a:Array) - { - return a[Math.floor(Math.random() * a.length)]; - } - - /** - * Returns n elements of array a, up to a maximum of a's length. - * If forceCopy is set, the returned array will always be a new instance. - */ - public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array - { - if (a.length <= n || a.length == 0) - { - if (forceCopy) return a.concat(); - else return a; - } - if (n == 1) return [PickRandom(a)]; - - var shuffled:Array = GetShuffledArray(a); - return shuffled.slice(0, n); - } - - /** - * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. - * If you want a new, shuffled array, use GetShuffledArray - */ - public static function randomSort(a:*, b:*) : Number - { - if (Math.random() < 0.5) return -1; - else return 1; - } - - /** - * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. - * If inPlace, a1 and a2 will be sorted. - * If they already contain duplicates, then all bets are off. - */ - public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array - { - var ret:Array = []; - var a1:Array = (inPlace) ? arr1 : arr1.slice(); - var a2:Array = (inPlace) ? arr2 : arr2.slice(); - - var len1:uint = a1.length; - var len2:uint = a2.length; - var i1:uint = 0; - var i2:uint = 0; - - //Boring cases - if (len1 == 0 && len2 == 0) return ret; - if (len1 == 0) return (inPlace) ? a2.slice() : a2; - if (len2 == 0) return (inPlace) ? a1.slice() : a1; - - if (sortFunc) - { - a1.sort(sortFunc); - a2.sort(sortFunc); - } - else - { - a1.sort(); - a2.sort(); - } - - while (i1 < len1) - { - //add all from a2 up to a1[i1] - while (i2 < len2 && a2[i2] <= a1[i1]) - { - ret.push(a2[i2]); - i2 += 1; - } - if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); - i1 += 1; - } - - while (i2 < len2) ret.push(a2[i2]); - - return ret; - } - - public static function ConvertToHHMMSS(seconds:Number):String - { - var s:Number = seconds % 60; - var m:Number = Math.floor((seconds % 3600 ) / 60); - var h:Number = Math.floor(seconds / (60 * 60)); - - var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; - var minuteStr:String = DoubleDigitFormat(m) + ":"; - var secondsStr:String = DoubleDigitFormat(s); - - return hourStr + minuteStr + secondsStr; - } - - public static function DoubleDigitFormat(num:uint):String - { - if (num < 10) - { - return ("0" + num); - } - return String(num); - } - - public static function CapitolizeString(str:String) : String - { - var firstChar:String = str.substr(0, 1); - var restOfString:String = str.substr(1, str.length); - - return firstChar.toUpperCase()+restOfString.toLowerCase(); - } - - // ^ Nice spelling, goof! - public static function CapitalizeString(str:String) : String - { - return CapitolizeString(str); - } - - public static function GetListString(listStrings:Array) : String - { - var andString:String = "&"; - var count:int = 0; - - var listString:String = ""; - for (var i = 0; i < listStrings.length; i++) - { - if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items - else if (count == listStrings.length-1 && listStrings.length > 2) - { - // For adding "and" at the end of 3+ items. It is: ", and $(item)" - var endingString:String = ""; - endingString = endingString.replace("$(item)", listStrings[i]); - listString += endingString; - count++; - continue; - } - else if (count > 0) listString += ", "; // Comma separated list - - listString += listStrings[i]; - count++; - } - - return listString; - } - - /* - * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) - * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." - */ - public static function ParseDate (dateString:String) : Date - { - var pattern:RegExp = /-/g; - var date = new Date(); - dateString = dateString.replace(pattern, "/"); - date.setTime(Date.parse(dateString)); - return date; - } - - /* - * For display only, not intended to be read by ParseDate - * Tuesday, June 7th, 2016 at 10:32 AM - */ - public static function FormatDate (date:Date) : String - { - var f:DateTimeFormatter = new DateTimeFormatter("en-US"); - var dateStr:String; - var lastChar:String; - - //Flash can't do "1st", "2nd", etc - - f.setDateTimePattern("d"); - dateStr = f.format(date); - lastChar = dateStr.charAt(dateStr.length - 1); - - if (lastChar == "1" && dateStr != "11") dateStr += "st"; - else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; - else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; - else dateStr += "th"; - - f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); - return f.format(date); - } - - /* Simply counts the number of properties on the object - */ - public static function CountObjectParameters(obj:Object):int - { - var cnt:int=0; - - for (var s:String in obj) cnt++; - - return cnt; - } - - /** - * For when shit gets real - */ - public static function PrintStackTrace() - { - try { - throw new Error('StackTrace'); - } catch (e:Error) { - _strace(e.getStackTrace()); - } - } } } \ No newline at end of file diff --git a/blooddy_crypto/LICENSE.md b/blooddy_crypto/LICENSE.md new file mode 100755 index 0000000..00ad983 --- /dev/null +++ b/blooddy_crypto/LICENSE.md @@ -0,0 +1,24 @@ +MIT License +=========== + +Copyright (C) 2010 Nick Ryzhy / blooddy@tut.by / www.blooddy.by + +----------- +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +----------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/blooddy_crypto/blooddy_crypto.swc b/blooddy_crypto/blooddy_crypto.swc new file mode 100755 index 0000000..ba33cc4 --- /dev/null +++ b/blooddy_crypto/blooddy_crypto.swc Binary files differ diff --git a/exporter.py b/exporter.py index 027380d..e20dbc6 100755 --- a/exporter.py +++ b/exporter.py @@ -109,7 +109,6 @@ def handle_command(msg_str): # return False to quit the driver loop msg = json.loads(msg_str) - print msg if "command" in msg: cmd = msg["command"] if cmd == "exit": diff --git a/job.py b/job.py index d100368..d4e73e8 100644 --- a/job.py +++ b/job.py @@ -1,4 +1,5 @@ import os.path +import base64 from args import * class Job: @@ -9,10 +10,16 @@ self.id = Job.next_id Job.next_id += 1 self.input = abspath(input) - self.base = base if base is not None else os.path.split(input)[0] + split = os.path.split(input) + self.base = base if base is not None else split[0] if not file_in_path(self.input, self.base): raise Exception("Failed: " + input + " is not in base dir " + self.base) self.type = type self.scale = scale + self.name = os.path.splitext(split[1])[0] + self.done = False def get_cmd(self): - return {"type":self.type, "scale":self.scale, "id":self.id} + with open(self.input, mode="rb") as f: + contents = f.read() + + return {"type":self.type, "scale":self.scale, "id":self.id, "name":self.name, "input":base64.b64encode(contents)} diff --git a/old/Utils.as b/old/Utils.as new file mode 100755 index 0000000..02b4f12 --- /dev/null +++ b/old/Utils.as @@ -0,0 +1,1202 @@ +package old +{ + /* This class has functions similar to the Utils.as in the /flash/Dialogs folder. However, some of + * those functions are different here than in /flash/Dialogs/Utils.as for... reasons? flash folder reasons! + */ + import flash.utils.*; + import flash.net.*; + import flash.display.*; + import flash.text.TextField; + import flash.text.TextFormat; + import flash.text.TextFieldType; + import flash.text.TextFieldAutoSize; + import flash.text.TextFormatAlign; + import flash.geom.Point; + import flash.geom.Matrix; + import flash.geom.Rectangle; + import flash.geom.ColorTransform; + import fl.motion.Color; + import fl.transitions.Tween; + import fl.transitions.easing.*; + import fl.transitions.TweenEvent; + import flash.net.navigateToURL; + import flash.external.ExternalInterface; + import flash.system.Capabilities; + import flash.filters.*; + import flash.filters.ColorMatrixFilter; + import com.adobe.images.JPGEncoder; + import flash.globalization.DateTimeFormatter; + + import djarts.utils.Base64; + import djarts.utils.PNGEnc; + import User.UserOptions; + + public class Utils + { + //["K","M","B","T","q", "Q", "s", "S","O","N","d","U","D","!","@","#","$","%","^","&","*"] + static var symbols = ["K","M","B","t","q", "Q", "s", "S","o","n","d","U","D","T","Qt","Qd","Sd","St","O","N","v","c"]; + static var divisors = []; + + public static function FormatBigNumber(number:*, round:Boolean=false):String + { + if (number < 0) return '-' + FormatBigNumber(Math.abs(number), round); + + var isWholeNumber = (Math.floor(number) == number); + round = round || isWholeNumber; + + if (number < 1000) + { + if (round) + { + return Math.round(number).toString(); + } + else + { + var decimalPlaces = (number >= 100) ? 1 : 2; // Below 100, show two decimal places. Above, only one. + var roundMult = Math.pow(10, decimalPlaces); + var rounded = Math.round(number); + var bigRounded = Math.round(number * roundMult); + var roundedDifferenceProportion = Math.abs(bigRounded / roundMult - rounded) / rounded; + + if (roundedDifferenceProportion < 0.001) + { + // Not a whole number, but the decimal places aren't worth showing + // Below also handles this, but is slower + return rounded.toString(); + } + else + { + var str:String = bigRounded.toString(); + str = str.substr(0, str.length - decimalPlaces) + "." + str.substr(str.length - decimalPlaces); + + while (str.charAt(str.length - 1) == "0") str = str.substr(0, str.length - 1); //should only ever happen once + if (str.charAt(str.length - 1) == ".") str = str.substr(0, str.length - 1); //probably won't happen at all + + return str; + } + } + } + + // Determine which symbol to use + var power = Math.floor(Math.log(number) / Math.log(1000)); + var index = Math.min(power-1, symbols.length-1); + var amount = number / Math.pow(1000, index+1); + var symbol = (index >= 0 && index < symbols.length) ? symbols[index] : ""; + + // If it's too big for a symbol (or if we just WANT to) + if (amount >= 1000 || UserOptions.ForceScientific) + { + // scientific notation + var power = Math.floor(Math.log(number) / Math.log(10)); + var num = number / Math.pow(10, power); + if (num == 10) { + num = 1; + power += 1; + } + var numString = "" + num; + numString = numString.substr(0, Math.min(4, numString.length)); + return numString + "e" + power; + + } + else + { + // Format with the symbol + // determine number of whole digits (will dictate how many decimals we show) + var whole = Math.floor(amount); + var amount_str:String = String(whole); + + var decimalDivider = 100/Math.pow(10,amount_str.length-1); + + //round to nearest decimal place + amount = int(amount*decimalDivider)/decimalDivider; + + var amountString:String = amount.toString(); + + var noDecimal:String = amountString.replace(".",""); + if (noDecimal.length == 2) + { + if (amountString.indexOf(".") != -1) amountString += "0"; + else amountString += ".0"; + } + else if (noDecimal.length == 1) amountString += ".00"; + + return amountString+symbol; // concat symbol + } + } + + private static var BigNumberRegex = new RegExp(/(\d*),?(\d*)(.*)/); + // Note-DG: This is mostly just used for definitions in the database, that don't require precision. + // This way we can define values in the database as 100B instead of 100000000000. + public static function ParseBigNumberString(number:String):Number + { + var regexArray:Array = BigNumberRegex.exec(number); + var magnitude = symbols.indexOf(regexArray[3]); + var thousands:Number; + if (regexArray[1]) { + thousands = regexArray[1]; + if (regexArray[2]) { // if numbers are split by comma, multiply by 1000 + thousands *= 1000; + } + } else { + thousands = 0; + } + var hundreds:Number = regexArray[2] ? regexArray[2] : 0; + + return (thousands + hundreds) * Math.pow(1000, magnitude + 1); + } + + public static function ParseNumberRange(range:String):Array + { + var split:Array = range.split(','); + return [Number(split[0]), Number(split[1])]; + } + + public static function DesaturateFilter() + { + var desatMatrix:Array = []; + var cmFilter; + + desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // red + desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // green + desatMatrix = desatMatrix.concat([0.309, 0.609, 0.082, 0, 0]); // blue + desatMatrix = desatMatrix.concat([0, 0, 0, 1, 0]); // alpha + cmFilter = new ColorMatrixFilter(desatMatrix); + + return cmFilter; + } + + public static function GetUserAgent():String + { + try + { + var userAgent = ExternalInterface.call("window.navigator.userAgent.toString"); + var browser:String = "[Unknown Browser]"; + + if (userAgent.indexOf("Safari") != -1) + { + browser = "Safari"; + } + if (userAgent.indexOf("Firefox") != -1) + { + browser = "Firefox"; + } + if (userAgent.indexOf("Chrome") != -1) + { + browser = "Chrome"; + } + if (userAgent.indexOf("MSIE") != -1) + { + browser = "Internet Explorer"; + } + if (userAgent.indexOf("Opera") != -1) + { + browser = "Opera"; + } + } + catch (e:Error) + { + //could not access ExternalInterface in containing page + return "[No ExternalInterface]"; + } + + return browser; + } + + public static function GetScreenshot(stage:Stage):String { + var scale:Number = 0.25; + var result:String = null; + var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH); + + var bData:BitmapData = new BitmapData(stage.stageWidth * scale, + stage.stageHeight * scale, false, 0x348400); + var matrix:Matrix = new Matrix(); + matrix.scale(scale, scale); + + bData.draw(stage, matrix); + bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter); + + + var imgBytes:ByteArray = new JPGEncoder(80).encode(bData); + //var imgBytes:ByteArray = PNGEnc.encode(bData); + if (imgBytes) { + var screenshotBase64:String = Base64.encode(imgBytes); + if (screenshotBase64) { + result = screenshotBase64; + } + } + + return result; + } + + public static function RecursivelyStop(clip, frame = null) + { + if (clip is MovieClip) + { + if (frame == null) + { + clip.stop(); + } else { + clip.gotoAndStop(frame); + } + } + if (clip is DisplayObjectContainer) + { + for (var i = 0; i < clip.numChildren; i++) + { + RecursivelyStop(clip.getChildAt(i)); + } + } + } + + public static function PlayerVersion() + { + + // Get the player's version by using the getVersion() global function. + var versionNumber:String = Capabilities.version; + + // The version number is a list of items divided by "," + var versionArray:Array = versionNumber.split(","); + var length:Number = versionArray.length; + //for(var i:Number = 0; i < length; i++) _strace("versionArray["+i+"]: "+versionArray[i]); + + // The main version contains the OS type too so we split it in two + // and we'll have the OS type and the major version number separately. + var platformAndVersion:Array = versionArray[0].split(" "); + //for(var j:Number = 0; j < 2; j++) _strace("platformAndVersion["+j+"]: "+platformAndVersion[j]); + //_strace("-----"); + + var majorVersion:Number = parseInt(platformAndVersion[1]); + var minorVersion:Number = parseInt(versionArray[1]); + var buildNumber:Number = parseInt(versionArray[2]); + + return Number(majorVersion+"."+minorVersion); + } + + + public static function OpenLocalURLTop(url) + { + navigateToURL(new URLRequest(GameSettings.Approot+url), "_top" ); + } + + public static function OpenLocalURL(url) + { + navigateToURL(new URLRequest(GameSettings.Approot+url), "_blank" ); + } + + public static function OpenURL(url, window = "_blank") + { + navigateToURL(new URLRequest(url), window); + } + + public static var ExitFullScreenCallback; + + public static function WallPublish(title:String, desc1:String, desc2:String, image:String, url = null, action = null) + { + if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); + //_strace(title + "\n" + desc1 + "\n" + desc2 + "\n" + image + "\n"); + ExternalInterface.call("askToPublish", title, url, desc1, desc2, image, action); + + //if (Settings.Platform == Settings.HI5) { + //DialogManager.Instance().ShowMessageBox("The message was posted to your wall!", "", "OK", null); + //} + } + + public static function SendToRecipients(recipients:Array, description, data) + { + if (!GameSettings.IsFacebook) return; + + if (Utils.ExitFullScreenCallback) Utils.ExitFullScreenCallback(); + try { + ExternalInterface.call("sendToRecipients", recipients, description ,data); + } + catch (e) + { + _strace(e.message); + } + } + + + public static function GetFriendData() + { + try { + return ExternalInterface.call("pollInviteData"); + } + catch (e) + { + _strace(e.message); + } + } + + + public static function singleBounceEase(t:Number, b:Number, c:Number, d:Number):Number + { + t = t / d; + if (t < 0.7) { + t *= 1.0 / 0.65; + return c * (t * t) + b; + } + return c * (t * t) + b; + } + + public static function Finish(e:TweenEvent) + { + //_strace("done " + e.currentTarget.obj.x + " " + e.currentTarget.obj.y + " " + e.currentTarget.obj.scaleX + " " + e.currentTarget.obj.scaleY); + e.currentTarget.removeEventListener(TweenEvent.MOTION_FINISH, Finish); + } + public static function Popup(mc, startScale = 0.8, finishCallback = null) + { + var rect:Rectangle = mc.getRect(mc); + var targetX = mc.x; + var targetY = mc.y; + var centerX = mc.x + rect.left + mc.width / 2.0; + var centerY = mc.y + rect.top + mc.height / 2.0; + var startX = centerX - (rect.left + mc.width / 2.0) * startScale; + var startY = centerY - (rect.top + mc.height / 2.0) * startScale; + var tweenSX = new Tween(mc, "scaleX", singleBounceEase, startScale, 1.0, 4, false); + if (finishCallback) tweenSX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); + var tweenSY = new Tween(mc, "scaleY", singleBounceEase, startScale, 1.0, 4, false); + if (finishCallback) tweenSY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); + var tweenX = new Tween(mc, "x", singleBounceEase, startX, targetX, 4, false); + if (finishCallback) tweenX.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); + var tweenY = new Tween(mc, "y", singleBounceEase, startY, targetY, 4, false); + if (finishCallback) tweenY.addEventListener(TweenEvent.MOTION_FINISH, finishCallback); + return [tweenSX, tweenSY, tweenX, tweenY]; + } + public static function StringSplit(s:String, delim:String, max:int = -1):Array + { + var ret:Array = s.split(delim); + if (max != -1) { + var more:String = ret.slice(max - 1).join(delim); + ret.splice(max - 1); + ret[max - 1] = more; + } + return ret; + } + + public static function StringStartsWith(str:String, substr:String):Boolean + { + if (substr.length > str.length) return false; + return (str.substr(0, substr.length) == substr); + } + + public static function StringEndsWith(str:String, substr:String):Boolean + { + if (substr.length > str.length) return false; + return (str.substr(str.length - substr.length, substr.length) == substr); + } + + public static function StringContains(str:String, substr:String):Boolean + { + return (str.indexOf(substr) !== -1); + } + + private static var vowelsAndH = { + "a":true, "A":true, + "e":true, "E":true, + "i":true, "I":true, + "o":true, "O":true, + "u":true, "U":true, + "h":true, "H":true + } + public static function StringStartsWithVowelOrH(s:String):Boolean + { + if (vowelsAndH[s.charAt(0)]) return true; + return false; + } + + public static function CopyObject(obj, except = null) + { + var i; + if (except == null) except = []; + if (obj is Array) { + var obj2 = []; + for (i = 0; i < obj.length; i++) { + obj2.push(Utils.CopyObject(obj[i])); + } + return obj2; + } + var ret:Object = {}; + for (i in obj) + { + if (except.indexOf(i) == -1) { + ret[i] = obj[i]; + } + } + + return ret; + } + public static function CopyToObject(objFrom, objTo, except = null) + { + if (except == null) except = []; + for (var i in objFrom) + { + if (except.indexOf(i) == -1) { + objTo[i] = objFrom[i]; + } + } + } + public static function CopyToObjectOnly(objFrom, objTo, only) + { + if (only == null) return; + for (var i in only) + { + if (objFrom.hasOwnProperty(only[i])) + { + objTo[only[i]] = objFrom[only[i]]; + } + } + } + + public static function ColorizeRGB(clip:MovieClip, r:int,g:int,b:int) + { + var cTransform = clip.transform.colorTransform; + cTransform.redOffset = r; + cTransform.greenOffset = g; + cTransform.blueOffset = b; + clip.transform.colorTransform = cTransform; + } + + public static function hex2rgb (hex):Object + { + var red = hex>>16; + var greenBlue = hex-(red<<16) + var green = greenBlue>>8; + var blue = greenBlue - (green << 8); + return({r:red, g:green, b:blue}); + } + + public static function RGBtoHEX(r, g, b) { + return r << 16 | g << 8 | b; + } + + /** + * NOTE: An alpha of 1 will make the object a solid color (good for silhouettes) + */ + public static function TintDisplayObject(obj:DisplayObject, color:uint = 0xffffff, alpha:Number = 1.0) + { + var cTint:Color = new Color(); + cTint.setTint(color, alpha); + obj.transform.colorTransform = cTint; + } + + // given an origin (ox, oy) and a look at point (tx, ty), + // and a clip with the given number of rotation states, which + // rotation should we pick? + public static function Rotation(ox, oy, tx, ty, rotations) + { + var delta:Point = new Point(tx - ox, ty - oy); + if (Point.distance(delta, new Point(0.0, 0.0)) < 0.00001) { + delta.y = -1.0; + } + var d = ( + (-Math.floor( + /* calculate the rotation and scale it */ + Math.atan2(delta.y, delta.x) / (Math.PI * 2.0) * rotations + + 0.5 // add 0.5 and take the floor (round to closest int) + ) + + rotations) // atan2 returns in the range -pi to pi, measured ccw from +x, + // we negate it and add rotations again to get it in the range + // [0, rotations] + % rotations) + 1; // add 1 to reference frames + return d; + } + /* performs multiple operations asynchronously, but wait for them all to finish: + * instead of calling a bunch of functions and passing callbacks, pass those callbacks to WaitForFunctions + * and use ret.callbacks[0], ret.callbacks[1], etc... as the callbacks + * this will wait until every command is complete and call all the callbacks at once. + * + * For instance, to load multiple graphics packs asynchronously and wait for them all to finish, + * call var ret = WaitForFunctions([DoneLoading, null, null, null]); to generate + * ret.callbacks[0]..ret.callbacks[3], and pass these to 4 calls to LoadExternalGraphics. + * When these 4 calls complete, the provided 4 functions will be called with the arguments returned + * from the callbacks (in this case, only DoneLoading will be called since the + * other callbacks are null). + */ + public static function WaitForFunctions(...funcs):Object + { + var ret:Object = {}; + // has a callback been hit? + ret.hit = new Array(funcs.length); + // what were the original arguments the callback was called with + ret.args = new Array(funcs.length); + // a list of the artifical callbacks we are providing + ret.callbacks = new Array(funcs.length); + // the real callbacks + ret.funcs = funcs; + ret.done = false; + + ret.immediate = []; + + for (var i = 0; i < funcs.length; i++) { + // we have to setup this temp callback in another function, because the anon function's + // activation object will contain the current scope, meaning that the variable + // i will be updated in each function; if we do it in a seperate function each + // activation object will reference a different i + ret.callbacks[i] = Utils.SetupFunction(ret, i); + } + return ret; + } + + /** + * Returns the standard money format for an integer amount + */ + public static function FormatCurrency(amount:int, symbol:String = "$"):String + { + var afterDecimal:String = (amount % 100).toString(); + while (afterDecimal.length < 2) afterDecimal = "0" + afterDecimal; //mmmm string concatenation + + var beforeDecimal:String; + if (amount > 100) + { + beforeDecimal = Math.floor(amount/100).toString(); + } + else + { + beforeDecimal = "0"; + } + + return symbol + beforeDecimal + "." + afterDecimal; + } + + public static function FormatNumber(amount){ + var whole = Math.floor(amount); + // convert the number to a string + var amount_str:String = String(whole); + var total_str:String = String(amount); + + var number_array:Array = []; + var start:Number; + var end:Number = amount_str.length; + while (end > 0) { + start = Math.max(end - 3, 0); + number_array.unshift(amount_str.slice(start, end)); + end = start; + } + + var point = total_str.indexOf("."); + + var ret = number_array.join(","); + if (point != -1 && point < total_str.length) + { + ret += total_str.substr(point); + } + + return ret; + } + + protected static function SetupFunction(ret, i):Function + { + var a:Function = + function(...rest) { + if (ret.immediate[i]) ret.immediate[i].apply(null, rest); + ret.hit[i] = true; + ret.args[i] = rest; + var ok:Boolean = true; + var j; + for (j = 0; j < ret.hit.length; j++) { + if (!ret.hit[j]) { ok = false; break; } + } + if (ok && !ret.done) { + ret.done = true; + for (j = 0; j < ret.funcs.length; j++) { + if (ret.funcs[j] != null) ret.funcs[j].apply(null, ret.args[j]); + } + } + }; + return a; + } + + // useful for the paned dialogs to show a certain pane/button + public static function OnlyVisible(obj, set:Array, index:int) + { + for (var i in set) { + if (i != index) { + obj[set[i]].visible = false; + } else { + obj[set[i]].visible = true; + } + } + } + public static function AllVisible(obj, set:Array) + { + for (var i in set) { + obj[set[i]].visible = true; + } + } + // set one of a list of tabs to be enabled + public static function OnlyToggled(obj, set:Array, index:int) + { + for (var i in set) { + if (i != index) { + obj[set[i]].SetToggled(false); + } else { + obj[set[i]].SetToggled(true); + } + } + } + // get the frame number of a label in the timeline + public static function GetLabelFrame(mc, name:String):int + { + for (var l in mc.currentLabels) { + if (mc.currentLabels[l].name == name) return mc.currentLabels[l].frame; + } + return 1; + } + // generate a quick text field of a certain color/style + public static function BasicTextField(color:uint, + size:int, + font:String, + text:String, + additional:Object = null, + align = "left"):TextField + { + var t:TextField = new TextField(); + var f:TextFormat = new TextFormat(); + f.align = align; + if (additional != null) for (var a in additional) f[a] = additional[a]; + f.font = font; + f.color = color; + f.size = size; + t.type = TextFieldType.DYNAMIC; + t.defaultTextFormat = f; + t.text = text; + t.selectable = false; + t.autoSize = TextFieldAutoSize.LEFT; + return t; + } + public static function var_dump(_obj, name = "Dump") + { + _strace(name + " " + (_obj) + " {"); + flash.utils.describeType(_obj); + var varList:XMLList = flash.utils.describeType(_obj)..variable; + + for(var i:int; i < varList.length(); i++) + { + //Show the name and the value + _strace(" " + varList[i].@name+' = '+ _obj[varList[i].@name]); + } + _strace("}"); + } + + public static function SetChildFrames(parentClip, frame, exclude = null) + { + if (parentClip is MovieClip && parentClip.name != exclude) + { + parentClip.gotoAndStop(frame); + for (var i = 0; i < parentClip.numChildren; i++) + { + Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); + } + } + } + + public static function SetChildFramesNoParent(parentClip, frame, exclude = null) + { + if (parentClip is MovieClip && parentClip.name != exclude) + { + for (var i = 0; i < parentClip.numChildren; i++) + { + Utils.SetChildFrames(parentClip.getChildAt(i), frame, exclude); + } + } + } + + //modifies the array passed as parameter, following the MO of the built in Array.sort() + public static function insertionSort(array:Array, compareFunction:Function):void + { + for(var i:int=1; i < array.length; i++) + { + var value:Object = array[i]; + var k:int=i-1; + while( k >= 0 && compareFunction(array[k], value) == -1) + { + array[k+1]=array[k]; + k--; + } + array[k+1]=value; + } + } + + + public static function Screenshot(sourceClip, receiverURL, filename) + { + + var jpgSource:BitmapData; + + if (sourceClip is Stage) + { + jpgSource = new BitmapData (sourceClip.stageWidth, sourceClip.stageHeight); + } else { + jpgSource = new BitmapData (sourceClip.width, sourceClip.height); + } + + jpgSource.draw(sourceClip); + + var jpgEncoder:JPGEncoder = new JPGEncoder(85); + var jpgStream:ByteArray = jpgEncoder.encode(jpgSource); + + var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream"); + var jpgURLRequest:URLRequest = new URLRequest(receiverURL+"?name="+filename); + jpgURLRequest.requestHeaders.push(header); + jpgURLRequest.method = URLRequestMethod.POST; + jpgURLRequest.data = jpgStream; + navigateToURL(jpgURLRequest, "_blank"); + + } + + + public static function SetColors(clip, color) + { + var colorTransform:ColorTransform; + + if (clip == null || color == null) return; + + if (clip.hasOwnProperty("outline") && clip.outline != null) + { + colorTransform = clip.outline.transform.colorTransform; + colorTransform.color = color.Outline; + clip.outline.transform.colorTransform = colorTransform; + } + + if (clip.hasOwnProperty("secondaryOutline") && clip.secondaryOutline != null) + { + colorTransform = clip.secondaryOutline.transform.colorTransform; + colorTransform.color = color.LightOutline; + clip.secondaryOutline.transform.colorTransform = colorTransform; + } + + if (clip.hasOwnProperty("color") && clip.color != null) + { + colorTransform = clip.color.transform.colorTransform; + colorTransform.color = color.Primary; + clip.color.transform.colorTransform = colorTransform; + } + + if (clip.hasOwnProperty("secondaryColor") && clip.secondaryColor != null) + { + colorTransform = clip.secondaryColor.transform.colorTransform; + colorTransform.color = color.Secondary; + clip.secondaryColor.transform.colorTransform = colorTransform; + } + + if (clip.hasOwnProperty("shadow") && clip.shadow != null) + { + colorTransform = clip.shadow.transform.colorTransform; + colorTransform.color = color.Shadow; + clip.shadow.transform.colorTransform = colorTransform; + } + + if (clip.hasOwnProperty("secondaryShadow") && clip.secondaryShadow != null) + { + colorTransform = clip.secondaryShadow.transform.colorTransform; + colorTransform.color = color.SecondaryShadow; + clip.secondaryShadow.transform.colorTransform = colorTransform; + } + } + /* returns a rect with the x, and y pos to center and the scaleX and scaleY as width and height */ + public static function GetUniformScaleRect(clip:MovieClip, maxWidth, maxHeight) + { + var rect:Rectangle = new Rectangle(0,0,0,0); + + var widthScale = Math.min(maxWidth / clip.width, 999); + var heightScale = Math.min(maxHeight / clip.height, 999); + + var scale = 1; + if (widthScale > heightScale) + { + scale = heightScale; + } else { + scale = widthScale; + } + + rect.width = clip.width * scale; + rect.height = clip.height * scale; + + var pb = clip.getBounds(clip); + var xadjust = -pb.left * scale; + var yadjust = -pb.top * scale; + + rect.x = xadjust + (maxWidth - rect.width) / 2; + rect.y = yadjust + (maxHeight - rect.height) / 2; + + rect.width = scale; + rect.height = scale; + + return rect; + } + + public static function Dec2Hex(d) + { + var chars:String = "0123456789ABCDEF"; + var str:String = ""; + while (d > 0 || str.length < 2) + { + var digit = d % 16; + d = (d - digit) / 16; + str = chars.charAt(digit) + str; + } + return str; + } + + public static function Hex2Dec(h:String) + { + var chars:String = "0123456789ABCDEF"; + var val = 1; + var res = 0; + for (var i = h.length - 1; i >= 0; i--) + { + res += chars.indexOf(h.substr(i, 1)) * val; + val *= 16; + } + return res; + } + + public static function ShallowCopyArray(array:Array) + { + if (!array) return null; + + var newArray:Array = []; + for (var i:int = 0; i < array.length; i++) + { + newArray.push(array[i]); + } + return newArray; + } + + /* Note: Will fail if any items in either array have reference type semantics (unless they point to the same object) + * (as opposed to value type semantics) + */ + public static function areEqual(a:Array,b:Array):Boolean { + if(a.length != b.length) { + return false; + } + var len:int = a.length; + for(var i:int = 0; i < len; i++) { + if(a[i] !== b[i]) { + return false; + } + } + return true; + } + + /* Note: Will fail if any items in either array have reference type semantics + * (as opposed to value type semantics) + */ + public static function objectsAreEqual(a:Object,b:Object):Boolean { + + for (var i in a) + { + if (!b.hasOwnProperty(i) || a[i] != b[i]) return false; + } + + return true; + } + + public static function DeepCopyClone (source : Object) : * + { + var array : ByteArray = new ByteArray (); + + array.writeObject (source); + array.position = 0; + + return array.readObject (); + } + + // {a:1, b:2} => [1,2] + public static function ObjectValues (obj:Object):Array { + var array = []; + for (var key in obj) array.push(obj[key]); + return array; + } + + // {a:1, b:2} => ["a","b"] + public static function ObjectKeys (obj:Object):Array { + var array = []; + for (var key in obj) array.push(key); + return array; + } + + // normal random variate generator; mean m, standard deviation s + public static function BoxMullerRandomNormal(m:Number, s:Number) : Number + { + var x1, x2, w, y1:Number; + var y2:Number; + var use_last:Boolean = false; + + if (use_last == true) /* use value from previous call */ + { + y1 = y2; + use_last = false; + } + else + { + do { + x1 = 2.0 * Math.random() - 1.0; + x2 = 2.0 * Math.random() - 1.0; + w = x1 * x1 + x2 * x2; + } while ( w >= 1.0 ); + + w = Math.sqrt( (-2.0 * Math.log( w ) ) / w ); + y1 = x1 * w; + y2 = x2 * w; + use_last = true; + } + + return( m + y1 * s ); + } + + public static function SanitizeNumber(n) + { + if (n is Number) + { + if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return 0; + } + return n; + } + + public static function IsNumberInvalid(n) + { + if (n is Number) + { + if (n == Number.NEGATIVE_INFINITY || n == Number.POSITIVE_INFINITY || n == Number.NaN) return true; + } + return false; + } + + public static function LimitNumberToMax(n) + { + if (n == Number.POSITIVE_INFINITY) return Number.MAX_VALUE; + return n; + } + + /* + value= Math.round(20/7); + value= int((20/7)*10)/10; + value= int((20/7)*100)/100; + value= int((20/7)*1000)/1000; + value= int((20/7)*10000)/10000; + */ + public static function RoundToDecimalPlaces(number:Number, places:int) + { + return Math.round((number)*Math.pow(10,places))/Math.pow(10,places); + } + + public static function GetShuffledArray(a:Array) : Array + { + var r:Array = a.concat(); + r.sort(randomSort); + return r; + } + + ///Convenience function since I keep forgetting the name of randomSort (hint: it's randomSort) + public static function ShuffleArray(a:Array) + { + a.sort(randomSort); + } + + public static function PickRandom(a:Array) + { + return a[Math.floor(Math.random() * a.length)]; + } + + /** + * Returns n elements of array a, up to a maximum of a's length. + * If forceCopy is set, the returned array will always be a new instance. + */ + public static function PickRandomSet(a:Array, n:int, forceCopy:Boolean=false):Array + { + if (a.length <= n || a.length == 0) + { + if (forceCopy) return a.concat(); + else return a; + } + if (n == 1) return [PickRandom(a)]; + + var shuffled:Array = GetShuffledArray(a); + return shuffled.slice(0, n); + } + + /** + * Does not randomly sort an array! To do that, Use the default array.sort with this as its argument. + * If you want a new, shuffled array, use GetShuffledArray + */ + public static function randomSort(a:*, b:*) : Number + { + if (Math.random() < 0.5) return -1; + else return 1; + } + + /** + * Returns the union of arr1 and arr2. If the elements are not primitive types, you'll need to provide a sorting function. + * If inPlace, a1 and a2 will be sorted. + * If they already contain duplicates, then all bets are off. + */ + public static function MergeArrays(arr1:Array, arr2:Array, sortFunc:Function = null, inPlace:Boolean = false) : Array + { + var ret:Array = []; + var a1:Array = (inPlace) ? arr1 : arr1.slice(); + var a2:Array = (inPlace) ? arr2 : arr2.slice(); + + var len1:uint = a1.length; + var len2:uint = a2.length; + var i1:uint = 0; + var i2:uint = 0; + + //Boring cases + if (len1 == 0 && len2 == 0) return ret; + if (len1 == 0) return (inPlace) ? a2.slice() : a2; + if (len2 == 0) return (inPlace) ? a1.slice() : a1; + + if (sortFunc) + { + a1.sort(sortFunc); + a2.sort(sortFunc); + } + else + { + a1.sort(); + a2.sort(); + } + + while (i1 < len1) + { + //add all from a2 up to a1[i1] + while (i2 < len2 && a2[i2] <= a1[i1]) + { + ret.push(a2[i2]); + i2 += 1; + } + if (ret.length == 0 || a1[i1] != ret[ret.length-1]) ret.push(a1[i1]); + i1 += 1; + } + + while (i2 < len2) ret.push(a2[i2]); + + return ret; + } + + public static function ConvertToHHMMSS(seconds:Number):String + { + var s:Number = seconds % 60; + var m:Number = Math.floor((seconds % 3600 ) / 60); + var h:Number = Math.floor(seconds / (60 * 60)); + + var hourStr:String = (h == 0) ? "" : DoubleDigitFormat(h) + ":"; + var minuteStr:String = DoubleDigitFormat(m) + ":"; + var secondsStr:String = DoubleDigitFormat(s); + + return hourStr + minuteStr + secondsStr; + } + + public static function DoubleDigitFormat(num:uint):String + { + if (num < 10) + { + return ("0" + num); + } + return String(num); + } + + public static function CapitolizeString(str:String) : String + { + var firstChar:String = str.substr(0, 1); + var restOfString:String = str.substr(1, str.length); + + return firstChar.toUpperCase()+restOfString.toLowerCase(); + } + + // ^ Nice spelling, goof! + public static function CapitalizeString(str:String) : String + { + return CapitolizeString(str); + } + + public static function GetListString(listStrings:Array) : String + { + var andString:String = "&"; + var count:int = 0; + + var listString:String = ""; + for (var i = 0; i < listStrings.length; i++) + { + if (count > 0 && listStrings.length == 2) listString += " "+andString+" "; // For just 2 items + else if (count == listStrings.length-1 && listStrings.length > 2) + { + // For adding "and" at the end of 3+ items. It is: ", and $(item)" + var endingString:String = ""; + endingString = endingString.replace("$(item)", listStrings[i]); + listString += endingString; + count++; + continue; + } + else if (count > 0) listString += ", "; // Comma separated list + + listString += listStrings[i]; + count++; + } + + return listString; + } + + /* + * Flash doesn't like the way MySQL prints dates (2016-06-02 13:00:00) + * "The year month and day terms can be separated by a forward slash (/) or by spaces, but never by a dash (-)." + */ + public static function ParseDate (dateString:String) : Date + { + var pattern:RegExp = /-/g; + var date = new Date(); + dateString = dateString.replace(pattern, "/"); + date.setTime(Date.parse(dateString)); + return date; + } + + /* + * For display only, not intended to be read by ParseDate + * Tuesday, June 7th, 2016 at 10:32 AM + */ + public static function FormatDate (date:Date) : String + { + var f:DateTimeFormatter = new DateTimeFormatter("en-US"); + var dateStr:String; + var lastChar:String; + + //Flash can't do "1st", "2nd", etc + + f.setDateTimePattern("d"); + dateStr = f.format(date); + lastChar = dateStr.charAt(dateStr.length - 1); + + if (lastChar == "1" && dateStr != "11") dateStr += "st"; + else if (lastChar == "2" && dateStr != "12") dateStr += "nd"; + else if (lastChar == "3" && dateStr != "13") dateStr += "rd"; + else dateStr += "th"; + + f.setDateTimePattern("EEEE, MMMM '" + dateStr + "', yyyy 'at' h:mm a"); + return f.format(date); + } + + /* Simply counts the number of properties on the object + */ + public static function CountObjectParameters(obj:Object):int + { + var cnt:int=0; + + for (var s:String in obj) cnt++; + + return cnt; + } + + /** + * For when shit gets real + */ + public static function PrintStackTrace() + { + try { + throw new Error('StackTrace'); + } catch (e:Error) { + _strace(e.getStackTrace()); + } + } + } +} \ No newline at end of file