PageRenderTime 4134ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Games/GirlSwordFlash/src/mochi/as3/MochiServices.as

http://flaswf.googlecode.com/
ActionScript | 725 lines | 557 code | 118 blank | 50 comment | 128 complexity | c2ad53c503369042127372605a7fee1c MD5 | raw file
  1. /**
  2. * MochiServices
  3. * Connection class for all MochiAds Remote Services
  4. * @author Mochi Media
  5. */
  6. package mochi.as3 {
  7. import flash.geom.Rectangle;
  8. import flash.display.DisplayObject;
  9. import flash.display.DisplayObjectContainer;
  10. import flash.display.Sprite;
  11. import flash.display.MovieClip;
  12. import flash.events.StatusEvent;
  13. import flash.events.TimerEvent;
  14. import flash.system.Security;
  15. import flash.system.Capabilities;
  16. import flash.display.Loader;
  17. import flash.display.LoaderInfo;
  18. import flash.events.Event;
  19. import flash.events.IOErrorEvent;
  20. import flash.net.URLRequest;
  21. import flash.net.URLRequestMethod;
  22. import flash.net.URLVariables;
  23. import flash.net.LocalConnection;
  24. import flash.net.navigateToURL;
  25. import flash.utils.Timer;
  26. import flash.utils.getTimer;
  27. import flash.utils.ByteArray;
  28. import flash.utils.Endian;
  29. import flash.utils.setTimeout;
  30. public class MochiServices {
  31. public static const CONNECTED:String = "onConnected";
  32. private static var _id:String;
  33. private static var _container:Object;
  34. private static var _clip:MovieClip;
  35. private static var _loader:Loader;
  36. private static var _timer:Timer;
  37. private static var _preserved:Object;
  38. private static var _servURL:String = "http://www.mochiads.com/static/lib/services/"
  39. private static var _services:String = "services.swf";
  40. private static var _mochiLC:String = "MochiLC.swf";
  41. private static var _swfVersion:String;
  42. private static var _listenChannelName:String = "__ms_";
  43. private static var _sendChannel:LocalConnection;
  44. private static var _sendChannelName:String;
  45. private static var _connecting:Boolean = false;
  46. private static var _connected:Boolean = false;
  47. public static var netup:Boolean = true;
  48. public static var netupAttempted:Boolean = false;
  49. public static var onError:Object;
  50. public static var widget:Boolean = false;
  51. private static var _mochiLocalConnection:MovieClip;
  52. private static var _queue:Array;
  53. private static var _nextCallbackID:Number;
  54. private static var _callbacks:Object;
  55. private static var _dispatcher:MochiEventDispatcher = new MochiEventDispatcher();
  56. //
  57. public static function get id ():String {
  58. return _id;
  59. }
  60. //
  61. public static function get clip ():Object {
  62. return _container;
  63. }
  64. //
  65. public static function get childClip ():Object {
  66. return _clip;
  67. }
  68. //
  69. //
  70. public static function getVersion():String {
  71. return "3.9.4 as3";
  72. }
  73. //
  74. //
  75. public static function allowDomains(server:String):String {
  76. if( flash.system.Security.sandboxType != "application" )
  77. {
  78. flash.system.Security.allowDomain("*");
  79. flash.system.Security.allowInsecureDomain("*");
  80. }
  81. if (server.indexOf("http://") != -1) {
  82. var hostname:String = server.split("/")[2].split(":")[0];
  83. if( flash.system.Security.sandboxType != "application" )
  84. {
  85. flash.system.Security.allowDomain(hostname);
  86. flash.system.Security.allowInsecureDomain(hostname);
  87. }
  88. }
  89. return hostname;
  90. }
  91. //
  92. //
  93. public static function isNetworkAvailable():Boolean {
  94. return Security.sandboxType != "localWithFile";
  95. }
  96. //
  97. public static function set comChannelName(val:String):void {
  98. if (val != null) {
  99. if (val.length > 3) {
  100. _sendChannelName = val + "_fromgame";
  101. initComChannels();
  102. }
  103. }
  104. }
  105. //
  106. public static function get connected ():Boolean {
  107. return _connected;
  108. }
  109. public static function warnID(bid:String, leaderboard:Boolean):void {
  110. bid = bid.toLowerCase();
  111. if( bid.length != 16 )
  112. {
  113. trace( "WARNING: " + (leaderboard?"board":"game") + " ID is not the appropriate length" );
  114. return ;
  115. }
  116. else if( bid == "1e113c7239048b3f" )
  117. {
  118. if( leaderboard )
  119. trace( "WARNING: Using testing board ID");
  120. else
  121. trace( "WARNING: Using testing board ID as game ID");
  122. return ;
  123. }
  124. else if( bid == "84993a1de4031cd8" )
  125. {
  126. if( leaderboard )
  127. trace( "WARNING: Using testing game ID as board ID");
  128. else
  129. trace( "WARNING: Using testing game ID");
  130. return ;
  131. }
  132. for( var i:Number = 0; i < bid.length; i++ )
  133. {
  134. switch( bid.charAt(i) )
  135. {
  136. case "0": case "1": case "2": case "3":
  137. case "4": case "5": case "6": case "7":
  138. case "8": case "9": case "a": case "b":
  139. case "c": case "d": case "e": case "f":
  140. continue ;
  141. default:
  142. trace( "WARNING: Board ID contains illegal characters: " + bid );
  143. return ;
  144. }
  145. }
  146. }
  147. /**
  148. * Method: connect
  149. * Connects your game to the MochiServices API
  150. * @param id the MochiAds ID of your game
  151. * @param clip the MovieClip in which to load the API (optional for all but AS3, defaults to _root)
  152. * @param onError a function to call upon connection or IO error
  153. */
  154. public static function connect (id:String, clip:Object, onError:Object = null):void {
  155. warnID( id, false );
  156. if (onError != null) {
  157. MochiServices.onError = onError;
  158. } else if (MochiServices.onError == null) {
  159. MochiServices.onError = function (errorCode:String):void { trace(errorCode); }
  160. }
  161. if (clip is DisplayObject) {
  162. if( clip.stage == null )
  163. {
  164. trace("MochiServices connect requires the containing clip be attached to the stage");
  165. }
  166. if (!_connected && _clip == null) {
  167. trace("MochiServices Connecting...");
  168. _connecting = true;
  169. init(id, clip);
  170. }
  171. } else {
  172. trace("Error, MochiServices requires a Sprite, Movieclip or instance of the stage.");
  173. }
  174. }
  175. public static function disconnect ():void {
  176. if (_connected || _connecting) {
  177. if (_clip != null) {
  178. if (_clip.parent != null) {
  179. if (_clip.parent is Sprite) {
  180. Sprite(_clip.parent).removeChild(_clip);
  181. _clip = null;
  182. }
  183. }
  184. }
  185. _connecting = _connected = false;
  186. flush(true);
  187. try {
  188. _mochiLocalConnection.close();
  189. } catch (error:Error) { }
  190. }
  191. if (_timer != null) {
  192. try {
  193. _timer.stop();
  194. _timer.removeEventListener(TimerEvent.TIMER, connectWait);
  195. _timer = null;
  196. } catch (error:Error) { }
  197. }
  198. }
  199. public static function stayOnTop ():void {
  200. _container.addEventListener(Event.ENTER_FRAME, MochiServices.bringToTop, false, 0, true);
  201. if (_clip != null) { _clip.visible = true; }
  202. }
  203. public static function doClose ():void {
  204. _container.removeEventListener(Event.ENTER_FRAME, MochiServices.bringToTop);
  205. }
  206. public static function bringToTop (e:Event = null):void {
  207. if (MochiServices.clip != null && MochiServices.childClip != null) {
  208. try {
  209. if (MochiServices.clip.numChildren > 1) {
  210. MochiServices.clip.setChildIndex(MochiServices.childClip, MochiServices.clip.numChildren - 1);
  211. }
  212. } catch (errorObject:Error) {
  213. trace("Warning: Depth sort error.");
  214. _container.removeEventListener(Event.ENTER_FRAME, MochiServices.bringToTop);
  215. }
  216. }
  217. }
  218. //
  219. //
  220. private static function init (id:String, clip:Object):void {
  221. _id = id;
  222. if (clip != null) {
  223. _container = clip;
  224. loadCommunicator(id, _container);
  225. }
  226. }
  227. //
  228. //
  229. public static function setContainer (container:Object = null, doAdd:Boolean = true):void {
  230. if( _clip.parent )
  231. _clip.parent.removeChild(_clip);
  232. if (container != null) {
  233. if (container is DisplayObjectContainer) _container = container;
  234. }
  235. if (doAdd) {
  236. if (_container is DisplayObjectContainer) {
  237. DisplayObjectContainer(_container).addChild(_clip);
  238. }
  239. }
  240. }
  241. //
  242. //
  243. private static function loadCommunicator (id:String, clip:Object):MovieClip {
  244. if (_clip != null) {
  245. return _clip;
  246. }
  247. if (!MochiServices.isNetworkAvailable()) {
  248. MochiServices.onError("NotConnected");
  249. return null;
  250. }
  251. if (urlOptions(clip).servURL) {
  252. _servURL = urlOptions(clip).servURL;
  253. }
  254. var servicesURL:String = _servURL + _services;
  255. if (urlOptions(clip).servicesURL) {
  256. servicesURL = urlOptions(clip).servicesURL;
  257. }
  258. _listenChannelName += Math.floor((new Date()).time) + "_" + Math.floor(Math.random() * 99999);
  259. MochiServices.allowDomains(servicesURL);
  260. _clip = new MovieClip();
  261. loadLCBridge(_clip);
  262. // load services swf into container
  263. _loader = new Loader();
  264. _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, detach);
  265. _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, detach);
  266. _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);
  267. var req:URLRequest = new URLRequest(servicesURL);
  268. var vars:URLVariables = new URLVariables();
  269. // variables for services.swf
  270. vars.listenLC = _listenChannelName;
  271. vars.mochiad_options = clip.loaderInfo.parameters.mochiad_options;
  272. vars.api_version = getVersion();
  273. if( widget )
  274. vars.widget = true;
  275. req.data = vars;
  276. _loader.load(req);
  277. _clip.addChild(_loader);
  278. // init send channel
  279. _sendChannel = new LocalConnection();
  280. _queue = [];
  281. _nextCallbackID = 0;
  282. _callbacks = {};
  283. _timer = new Timer(10000, 1);
  284. _timer.addEventListener(TimerEvent.TIMER, connectWait);
  285. _timer.start();
  286. return _clip;
  287. }
  288. private static function detach( event:Event ):void
  289. {
  290. // Remove event listeners for this Loader
  291. var loader:LoaderInfo = LoaderInfo(event.target);
  292. loader.removeEventListener( Event.COMPLETE, detach );
  293. loader.removeEventListener( IOErrorEvent.IO_ERROR, detach );
  294. loader.removeEventListener( Event.COMPLETE, loadLCBridgeComplete );
  295. loader.removeEventListener( IOErrorEvent.IO_ERROR, loadError );
  296. }
  297. private static function loadLCBridge(clip:Object):void {
  298. var loader:Loader = new Loader();
  299. var mochiLCURL:String = _servURL + _mochiLC;
  300. var req:URLRequest = new URLRequest(mochiLCURL);
  301. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, detach);
  302. loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, detach);
  303. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadLCBridgeComplete);
  304. loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);
  305. loader.load(req);
  306. clip.addChild(loader);
  307. }
  308. private static function loadLCBridgeComplete( e:Event ):void
  309. {
  310. var loader:Loader = LoaderInfo(e.target).loader;
  311. _mochiLocalConnection = MovieClip(loader.content);
  312. listen();
  313. }
  314. private static function loadError(ev:Object):void {
  315. _clip._mochiad_ctr_failed = true;
  316. trace("MochiServices could not load.");
  317. MochiServices.disconnect();
  318. MochiServices.onError("IOError");
  319. }
  320. //
  321. //
  322. public static function connectWait (e:TimerEvent):void {
  323. if (!_connected) {
  324. _clip._mochiad_ctr_failed = true;
  325. trace("MochiServices could not load. (timeout)");
  326. MochiServices.disconnect();
  327. MochiServices.onError("IOError");
  328. }
  329. else
  330. {
  331. _timer.stop();
  332. _timer.removeEventListener(TimerEvent.TIMER, connectWait);
  333. _timer = null;
  334. }
  335. }
  336. //
  337. //
  338. private static function listen ():void {
  339. _mochiLocalConnection.connect(_listenChannelName);
  340. _clip.handshake = function (args:Object):void { MochiServices.comChannelName = args.newChannel; }
  341. trace("Waiting for MochiAds services to connect...");
  342. }
  343. //
  344. //
  345. private static function initComChannels ():void {
  346. if (!_connected) {
  347. trace("[SERVICES_API] connected!");
  348. _connecting = false;
  349. _connected = true;
  350. _mochiLocalConnection.send(_sendChannelName, "onReceive", {methodName: "handshakeDone"});
  351. _mochiLocalConnection.send(_sendChannelName, "onReceive", {methodName: "registerGame", preserved:_preserved, id: _id, version: getVersion(), parentURL: _container.loaderInfo.loaderURL } );
  352. _clip.onReceive = onReceive;
  353. _clip.onEvent = onEvent;
  354. _clip.onError = function ():void { MochiServices.onError("IOError"); };
  355. while(_queue.length > 0) {
  356. _mochiLocalConnection.send(_sendChannelName, "onReceive", _queue.shift());
  357. }
  358. }
  359. }
  360. private static function onReceive(pkg:Object):void {
  361. var cb:String = pkg.callbackID;
  362. var cblst:Object = _callbacks[cb];
  363. if (!cblst) return;
  364. var method:* = cblst.callbackMethod;
  365. var methodName:String = "";
  366. var obj:Object = cblst.callbackObject;
  367. if (obj && typeof(method) == 'string') {
  368. methodName = method;
  369. if (obj[method] != null) {
  370. method = obj[method];
  371. } else {
  372. trace("Error: Method " + method + " does not exist.");
  373. }
  374. }
  375. if (method != undefined) {
  376. try {
  377. method.apply(obj, pkg.args);
  378. } catch (error:Error) {
  379. trace("Error invoking callback method '" + methodName + "': " + error.toString());
  380. }
  381. } else if (obj != null) {
  382. try {
  383. obj(pkg.args);
  384. } catch (error:Error) {
  385. trace("Error invoking method on object: " + error.toString());
  386. }
  387. }
  388. delete _callbacks[cb];
  389. }
  390. private static function onEvent(pkg:Object):void {
  391. var target:String = pkg.target;
  392. var event:String = pkg.event;
  393. switch( target )
  394. {
  395. // MochiServices core events
  396. case "services":
  397. MochiServices.triggerEvent( pkg.event, pkg.args );
  398. break ;
  399. // MochiEvents tunnel
  400. case "events":
  401. MochiEvents.triggerEvent( pkg.event, pkg.args );
  402. break ;
  403. // MochiSocial tunnel
  404. case "coins":
  405. MochiCoins.triggerEvent( pkg.event, pkg.args );
  406. break ;
  407. // MochiSocial tunnel
  408. case "social":
  409. MochiSocial.triggerEvent( pkg.event, pkg.args );
  410. break ;
  411. }
  412. }
  413. //
  414. //
  415. private static function flush (error:Boolean):void {
  416. var request:Object;
  417. var callback:Object;
  418. if (_clip && _queue) {
  419. while (_queue.length > 0) {
  420. request = _queue.shift();
  421. callback = null;
  422. if (request != null) {
  423. if (request.callbackID != null) callback = _callbacks[request.callbackID];
  424. delete _callbacks[request.callbackID];
  425. if (error && callback != null) {
  426. handleError(request.args, callback.callbackObject, callback.callbackMethod);
  427. }
  428. }
  429. }
  430. }
  431. }
  432. //
  433. //
  434. private static function handleError (args:Object, callbackObject:Object, callbackMethod:Object):void {
  435. if (args != null) {
  436. if (args.onError != null) {
  437. args.onError("NotConnected");
  438. }
  439. if (args.options != null && args.options.onError != null) {
  440. args.options.onError("NotConnected");
  441. }
  442. }
  443. if (callbackMethod != null) {
  444. args = { };
  445. args.error = true;
  446. args.errorCode = "NotConnected";
  447. if (callbackObject != null && callbackMethod is String) {
  448. try {
  449. callbackObject[callbackMethod](args);
  450. } catch (error:Error) { }
  451. } else if (callbackMethod != null) {
  452. try {
  453. callbackMethod.apply(args);
  454. } catch (error:Error) { }
  455. }
  456. }
  457. }
  458. //
  459. //
  460. public static function send (methodName:String, args:Object = null, callbackObject:Object = null, callbackMethod:Object = null):void {
  461. if (_connected) {
  462. _mochiLocalConnection.send(_sendChannelName, "onReceive", {methodName: methodName, args: args, callbackID: _nextCallbackID});
  463. } else if (_clip == null || !_connecting) {
  464. trace( "Error: MochiServices not connected. Please call MochiServices.connect(). Function: " + methodName);
  465. handleError(args, callbackObject, callbackMethod);
  466. flush(true);
  467. return;
  468. } else {
  469. _queue.push({methodName: methodName, args: args, callbackID: _nextCallbackID});
  470. }
  471. if (_clip != null) {
  472. if (_callbacks != null ) {
  473. _callbacks[_nextCallbackID] = {callbackObject: callbackObject, callbackMethod: callbackMethod};
  474. _nextCallbackID++;
  475. }
  476. }
  477. }
  478. private static function urlOptions(clip:Object):Object {
  479. var opts:Object = {};
  480. var options:String;
  481. if (clip.stage) {
  482. options = clip.stage.loaderInfo.parameters.mochiad_options;
  483. } else {
  484. options = clip.loaderInfo.parameters.mochiad_options;
  485. }
  486. if (options) {
  487. var pairs:Array = options.split("&");
  488. for (var i:Number = 0; i < pairs.length; i++) {
  489. var kv:Array = pairs[i].split("=");
  490. opts[unescape(kv[0])] = unescape(kv[1]);
  491. }
  492. }
  493. return opts;
  494. }
  495. public static function addLinkEvent(url:String, burl:String, btn:DisplayObjectContainer, onClick:Function = null):void {
  496. var vars:Object = new Object();
  497. var avm1Click:DisplayObject;
  498. vars["mav"] = getVersion();
  499. vars["swfv"] = "9";
  500. vars["swfurl"] = btn.loaderInfo.loaderURL;
  501. vars["fv"] = Capabilities.version;
  502. vars["os"] = Capabilities.os;
  503. vars["lang"] = Capabilities.language;
  504. vars["scres"] = (Capabilities.screenResolutionX + "x" + Capabilities.screenResolutionY);
  505. var s:String = "?";
  506. var i:Number = 0;
  507. for (var x:String in vars) {
  508. if (i != 0) s = s + "&";
  509. i++;
  510. s = s + x + "=" + escape(vars[x]);
  511. }
  512. var req:URLRequest = new URLRequest("http://link.mochiads.com/linkping.swf");
  513. var loader:Loader = new Loader();
  514. var setURL:Function = function(url:String):void {
  515. if (avm1Click) {
  516. btn.removeChild(avm1Click);
  517. }
  518. avm1Click = clickMovie(url, onClick );
  519. var rect:Rectangle = btn.getBounds(btn);
  520. btn.addChild(avm1Click);
  521. avm1Click.x = rect.x;
  522. avm1Click.y = rect.y;
  523. avm1Click.scaleX = 0.01 * rect.width;
  524. avm1Click.scaleY = 0.01 * rect.height;
  525. }
  526. var err:Function = function (ev:Object):void {
  527. netup = false;
  528. ev.target.removeEventListener(ev.type, arguments.callee);
  529. setURL(burl);
  530. }
  531. var complete:Function = function(ev:Object):void {
  532. ev.target.removeEventListener(ev.type, arguments.callee);
  533. }
  534. if (netup) {
  535. setURL(url + s);
  536. } else {
  537. setURL(burl);
  538. }
  539. if (! ( netupAttempted || _connected )) {
  540. netupAttempted = true;
  541. loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, err);
  542. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
  543. loader.load(req);
  544. }
  545. }
  546. private static function clickMovie(url:String, cb:Function):MovieClip {
  547. var avm1_bytecode:Array = [150, 21, 0, 7, 1, 0, 0, 0, 0, 98, 116, 110, 0, 7, 2, 0, 0, 0, 0, 116, 104, 105, 115, 0, 28, 150, 22, 0, 0, 99, 114, 101, 97, 116, 101, 69, 109, 112, 116, 121, 77, 111, 118, 105, 101, 67, 108, 105, 112, 0, 82, 135, 1, 0, 0, 23, 150, 13, 0, 4, 0, 0, 111, 110, 82, 101, 108, 101, 97, 115, 101, 0, 142, 8, 0, 0, 0, 0, 2, 42, 0, 114, 0, 150, 17, 0, 0, 32, 0, 7, 1, 0, 0, 0, 8, 0, 0, 115, 112, 108, 105, 116, 0, 82, 135, 1, 0, 1, 23, 150, 7, 0, 4, 1, 7, 0, 0, 0, 0, 78, 150, 8, 0, 0, 95, 98, 108, 97, 110, 107, 0, 154, 1, 0, 0, 150, 7, 0, 0, 99, 108, 105, 99, 107, 0, 150, 7, 0, 4, 1, 7, 1, 0, 0, 0, 78, 150, 27, 0, 7, 2, 0, 0, 0, 7, 0, 0, 0, 0, 0, 76, 111, 99, 97, 108, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 0, 64, 150, 6, 0, 0, 115, 101, 110, 100, 0, 82, 79, 150, 15, 0, 4, 0, 0, 95, 97, 108, 112, 104, 97, 0, 7, 0, 0, 0, 0, 79, 150, 23, 0, 7, 255, 0, 255, 0, 7, 1, 0, 0, 0, 4, 0, 0, 98, 101, 103, 105, 110, 70, 105, 108, 108, 0, 82, 23, 150, 25, 0, 7, 0, 0, 0, 0, 7, 0, 0, 0, 0, 7, 2, 0, 0, 0, 4, 0, 0, 109, 111, 118, 101, 84, 111, 0, 82, 23, 150, 25, 0, 7, 100, 0, 0, 0, 7, 0, 0, 0, 0, 7, 2, 0, 0, 0, 4, 0, 0, 108, 105, 110, 101, 84, 111, 0, 82, 23, 150, 25, 0, 7, 100, 0, 0, 0, 7, 100, 0, 0, 0, 7, 2, 0, 0, 0, 4, 0, 0, 108, 105, 110, 101, 84, 111, 0, 82, 23, 150, 25, 0, 7, 0, 0, 0, 0, 7, 100, 0, 0, 0, 7, 2, 0, 0, 0, 4, 0, 0, 108, 105, 110, 101, 84, 111, 0, 82, 23, 150, 25, 0, 7, 0, 0, 0, 0, 7, 0, 0, 0, 0, 7, 2, 0, 0, 0, 4, 0, 0, 108, 105, 110, 101, 84, 111, 0, 82, 23, 150, 16, 0, 7, 0, 0, 0, 0, 4, 0, 0, 101, 110, 100, 70, 105, 108, 108, 0, 82, 23];
  548. var b:int;
  549. var header:Array = [
  550. 0x68, 0x00, 0x1f, 0x40, 0x00, 0x07, 0xd0, 0x00,
  551. 0x00, 0x0c, 0x01, 0x00, 0x43, 0x02, 0xff, 0xff,
  552. 0xff, 0x3f, 0x03
  553. ];
  554. var footer:Array = [0x00, 0x40, 0x00, 0x00, 0x00];
  555. var mc:MovieClip = new MovieClip();
  556. var lc:LocalConnection = new LocalConnection();
  557. var lc_name:String = "_click_" + Math.floor(Math.random() * 999999) + "_" + Math.floor((new Date()).time);
  558. lc = new LocalConnection();
  559. mc.lc = lc;
  560. mc.click = cb;
  561. lc.client = mc;
  562. lc.connect(lc_name)
  563. var ba:ByteArray = new ByteArray();
  564. var cpool:ByteArray = new ByteArray();
  565. cpool.endian = Endian.LITTLE_ENDIAN;
  566. cpool.writeShort(1);
  567. cpool.writeUTFBytes(url + " " + lc_name);
  568. cpool.writeByte(0);
  569. var actionLength:uint = avm1_bytecode.length + cpool.length + 4;
  570. var fileLength:uint = actionLength + 35;
  571. ba.endian = Endian.LITTLE_ENDIAN;
  572. ba.writeUTFBytes("FWS");
  573. ba.writeByte(8);
  574. ba.writeUnsignedInt(fileLength);
  575. for each (b in header) {
  576. ba.writeByte(b);
  577. }
  578. ba.writeUnsignedInt(actionLength);
  579. ba.writeByte(0x88);
  580. ba.writeShort(cpool.length);
  581. ba.writeBytes(cpool);
  582. for each (b in avm1_bytecode) {
  583. ba.writeByte(b);
  584. }
  585. for each (b in footer) {
  586. ba.writeByte(b);
  587. }
  588. var loader:Loader = new Loader();
  589. loader.loadBytes(ba);
  590. mc.addChild(loader);
  591. return mc;
  592. }
  593. // --- Callback system ----------
  594. public static function addEventListener( eventType:String, delegate:Function ):void
  595. {
  596. _dispatcher.addEventListener( eventType, delegate );
  597. }
  598. public static function triggerEvent( eventType:String, args:Object ):void
  599. {
  600. _dispatcher.triggerEvent( eventType, args );
  601. }
  602. public static function removeEventListener( eventType:String, delegate:Function ):void
  603. {
  604. _dispatcher.removeEventListener( eventType, delegate );
  605. }
  606. }
  607. }