In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

rc light client

please don't use this until it's done.
(it's never going to be done...)

memo: now uses native JSON
Get Adobe Flash player
by wh0 20 May 2012
// please don't use this until it's done.
package {
    import flash.desktop.*;
    import flash.display.*;
    import flash.events.*;
    import flash.external.*;
    import flash.net.*;
    import flash.system.*;
    import flash.utils.*;
    [SWF(width=1, height=1)]
    public class FlashTest extends Sprite {
        
        private function log(message:*):void {
            ExternalInterface.call('console.log', message);
        }
        
        private function error(e:*):void {
            ExternalInterface.call('console.error', String(e));
        }
        
        private function handleError(e:UncaughtErrorEvent):void {
            error(e.error);
        }
        
        private function makeLoad(loader:IEventDispatcher, name:String):void {
            ExternalInterface.call('updateLoad', name, 0, 0);
            loader.addEventListener(ProgressEvent.PROGRESS, function (e:ProgressEvent):void {
                ExternalInterface.call('updateLoad', name, e.bytesLoaded, e.bytesTotal);
            });
        }
        
        private function completeLoad(name:String, size:Number):void {
            ExternalInterface.call('updateLoad', name, size, size);
        }
        
        public function FlashTest() {
            loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, handleError);
            Security.allowDomain('*');
            try { ExternalInterface.addCallback('appComplete', appComplete); }
            catch (e:Error) { return; }
            ExternalInterface.call('movieComplete');
        }
        
        private function appComplete(data:String):void {
            data = decodeURIComponent(data);
            completeLoad('app', data.length);
            var uid:String = /"user":"(\d+)"/.exec(data)[1];
            ExternalInterface.call('setUid', uid);
            
            var match:Object = /<form action="(https:\/\/cooking\.game\.playfish\.com\/.*?)"/.exec(data);
            var resource:String = match[1].replace(/&amp;/g, '&').replace('https', 'http');
            var end:int = data.indexOf('</form', match.index);
            var hidden:RegExp = /<input type="hidden" autocomplete="off" name="(.+?)" value="(.+?)" \/>/g;
            hidden.lastIndex = match.index;
            var body:URLVariables = new URLVariables();
            while (match = hidden.exec(data)) {
                if (match.index > end) break;
                body[match[1]] = match[2];
            }
            
            var request:URLRequest = new URLRequest(resource);
            request.data = body;
            request.method = URLRequestMethod.POST;
            var iframeLoader:URLLoader = new URLLoader(request);
            makeLoad(iframeLoader, 'iframe');
            iframeLoader.addEventListener(Event.COMPLETE, iframeComplete);
        }
        
        private var databases:Object = {
            'ingredient': null,
            'recipe': null,
            'avatar': null,
            'front': null,
            'restaurant': null,
            'perk': null
        };
        
        private var tokenMap:Object = {};
        
        private var remaining:int = 3;
        private var base:String;
        private var si_url:String;
        private var si_session_id:String;
        private var si_profile_base:String;
        private var si_purchase_base:String;
        
        private function iframeComplete(e:Event):void {
            completeLoad('iframe', e.target.bytesTotal);
            
            var data:String = e.target.data;
            var config:Object = JSON.parse(/PF\.Config\.createParameters\('config', ({.*})\);/.exec(data)[1]);
            var extra:Object = JSON.parse(/PF\.Config\.createParameters\('extra', ({.*})\);/.exec(data)[1]);
            var key:String;
            base = extra.resource_subdir;
            si_url = extra.rpc_url;
            si_session_id = extra.rpc_session_id;
            si_profile_base = config.game_profile_base;
            si_purchase_base = extra.purchase_base;
            
            for (key in databases) {
                remaining++;
                loadResource(key, readDatabase);
            }
            
            var gameLoader:Loader = new Loader();
            makeLoad(gameLoader.contentLoaderInfo, 'game');
            gameLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, gameComplete);
            gameLoader.load(new URLRequest(extra.swf_game_url),
                new LoaderContext(false, ApplicationDomain.currentDomain, SecurityDomain.currentDomain));
        }
        
        private function allFinished():void {
            if (--remaining) return;
            ExternalInterface.addCallback('addOfflineMoney', addOfflineMoney);
            ExternalInterface.addCallback('hire', hire);
            ExternalInterface.addCallback('sendMail', sendMail);
            ExternalInterface.addCallback('acceptFeedGiftMail', acceptFeedGiftMail);
            ExternalInterface.addCallback('fromInventoryToGame', fromInventoryToGame);
            ExternalInterface.addCallback('fromGameToInventory', fromGameToInventory);
            ExternalInterface.addCallback('sellPurchaseOwnedItem', sellPurchaseOwnedItem);
            ExternalInterface.addCallback('getUserInfo', getUserInfo);
            ExternalInterface.addCallback('consumeItem', consumeItem);
            ExternalInterface.addCallback('consumeIngredients', consumeIngredients);
            ExternalInterface.addCallback('autoGift', autoGift);
            ExternalInterface.call('allFinished');
        }
        
        private function loadResource(resource:String, reader:Function):void {
            var resourceLoader:URLLoader = new URLLoader(new URLRequest(base + resource + '.bin'));
            resourceLoader.dataFormat = URLLoaderDataFormat.BINARY;
            makeLoad(resourceLoader, resource);
            resourceLoader.addEventListener(Event.COMPLETE, function (e:Event):void {
                var data:ByteArray = e.target.data;
                completeLoad(resource, data.length);
                data.uncompress();
                reader(resource, new XML(data.toString()));
                allFinished();
            });
        }
        
        private function readDatabase(key:String, database:XML):void {
            databases[key] = database;
            var names:Array = [];
            var ids:Array = [];
            for each (var item:XML in database..item) {
                names.push(item.@name.toString());
                ids.push(item.@id.toString());
                tokenMap[item.@id] = item.@hash.toString();
            }
            ExternalInterface.call('setDatabase', key, names, ids);
        }
        
        private var CPGC:Object = null;
        private var CPGCR:Object = null;
        private var CPRC:Object = null;
        private var CPRS:Object = null;
        
        private var GameWorld:Object;
        private var RpcClient:Object;
        private var RpcRequestManager:Object;
        private var RpcEvent:Object;
        private var AuditChange:Object;
        private var AuditChangeAction:Object;
        private var NetworkUid:Object;
        
        private function gameComplete(e:Event):void {
            CPGC = new DLL('com.playfish.games.cooking::');
            CPGCR = new DLL('com.playfish.games.cooking.rpc::');
            CPRC = new DLL('com.playfish.rpc.cooking::');
            CPRS = new DLL('com.playfish.rpc.share::');
            
            GameWorld = CPGC.GameWorld;
            RpcClient = CPRC.RpcClient;
            RpcRequestManager = CPGCR.RpcRequestManager;
            RpcEvent = CPGCR.RpcEvent;
            NetworkUid = CPRS.NetworkUid;
            AuditChange = CPRC.AuditChange;
            AuditChangeAction = CPRC.AuditChangeAction;
            
            GameWorld.rpcClient = new RpcClient(new CPRS.ServerInfo(si_url, si_session_id, si_profile_base, si_purchase_base));
            var rm:Object = new RpcRequestManager(RpcClient.BATCHMODE_INORDER);
            rm.addEventListener(RpcEvent.SUCCESS, rpcInitSuccess);
            rm.addEventListener(RpcEvent.FAIL, rpcInitFail);
            rm.init();
            rm.commit();
            allFinished();
        }
        
        private function makeRpcLoad(name:String):void {
            completeLoad(name, 1024);
        }
        
        private var getUserProfileRpc:Object;
        
        private function rpcInitSuccess(e:Event):void {
            makeRpcLoad('init');
            var rm:Object = new RpcRequestManager(RpcClient.BATCHMODE_CONDITIONAL);
            rm.addEventListener(RpcEvent.SUCCESS, onRpcsSuccess);
            rm.addEventListener(RpcEvent.FAIL, onRpcsFail);
            getUserProfileRpc = rm.getUserProfile();
            rm.commit();
            allFinished();
        }
        
        private function rpcInitFail(e:Event):void {
            throw 'could not initialize rpc';
        }
        
        private function onRpcsSuccess(e:Event):void {
            makeRpcLoad('rpcs');
            var userInfo:Object = getUserProfileRpc.userInfo;
            
            var shift:Object = userInfo.shift;
            var timestamp:Number = 0;
            if (shift.shiftId) {
                var group:XMLList = databases['perk'].group.(@name == 'Shift');
                var item:XMLList = group.item.(@id == shift.shiftId);
                timestamp = shift.startTime + 60000 * parseInt(item.@workTime.toString(), 10);
            }
            ExternalInterface.call('setStatus', userInfo.restaurantName, timestamp);
            
            allFinished();
        }
        
        private function onRpcsFail(e:Event):void {
            throw 'onRpcsFail, lol';
        }
        
        private var saveVersion:int = 1;
        
        private function savePlayerProfile(auditChanges:Array):void {
            log('saving profile version ' + saveVersion);
            var auditChangeBatch:Object = new CPRC.AuditChangeBatch();
            auditChangeBatch.auditChanges = auditChanges;
            auditChangeBatch.saveVersion = saveVersion++;
            GameWorld.rpcClient.savePlayerProfile(getUserProfileRpc.userInfo, auditChangeBatch,
                onSavePlayerProfileOk, onSavePlayerProfileFail);
        }
        
        private function onSavePlayerProfileOk(success:Number, version:Number, serverTime:Date, newMails:Array,
            ingredientChanges:Array, timeToMaintenance:uint, gardenUpdates:Array, shift:Object, newChallenges:Array):void {
            log('save player profile ok: ' + success);
        }
        
        private function onSavePlayerProfileFail():void {
            throw 'save player profile fail';
        }
        
        private function addOfflineMoney(creditsDelta:int, times:int):void {
            if (saveVersion > 1) return error('cannot add offline money after first save');
            
            var auditChange:Object = new AuditChange();
            auditChange.action = AuditChangeAction.creditChangeOffLine;
            auditChange.creditsDelta = creditsDelta;
            var auditChanges:Array = [];
            
            for (var i:int = 0; i < times; i++) {
                auditChanges.push(auditChange);
            }
            
            savePlayerProfile(auditChanges);
        }
        
        private function hire(uid:String):void {
            log('now hiring');
            var employee:Object = new CPRC.Employee();
            employee.id = new NetworkUid(NetworkUid.FACEBOOK, uid, 0);
            employee.task = CPGC.GameUserEmployee.JOB_WAITOR;
            var auditChange:Object = new AuditChange();
            auditChange.action = AuditChangeAction.hireEmployee;
            auditChange.employees = [employee];
            
            savePlayerProfile([auditChange]);
        }
        
        private function sendMail(recipientId:String, globalItemId:int, number:int):void {
            log('sending mail');
            var mail:Object = new CPRC.Mail();
            mail.type = CPRC.RpcClient.MAIL_FAN_PAGE_ITEM;
            mail.message = '';
            mail.recipientId = new NetworkUid(NetworkUid.FACEBOOK, recipientId, 0);
            mail.globalItemIds = [globalItemId];
            GameWorld.rpcClient.beginBatch(RpcClient.BATCHMODE_CONDITIONAL);
            var success:int = 0;
            var fail:int = 0;
            var notify:Function = function ():void {
                log('mailing results: ' + success + ' succeeded, ' + fail + ' failed');
            }
            
            for (var i:int = 0; i < number; i++) {
                GameWorld.rpcClient.sendMail(mail,
                    function (e:Number):void {
                        if (e) log('mail sent ' + e);
                        if (++success + fail == number) notify();
                    },
                    function ():void {
                        if (success + ++fail == number) notify();
                    }
                );
            }
            
            GameWorld.rpcClient.endBatch();
        }
        
        private var getReceivedMailsRpc:Object;
        
        private function acceptFeedGiftMail():void {
            log('getting received mails');
            var rm:Object = new RpcRequestManager(RpcClient.BATCHMODE_CONDITIONAL);
            rm.addEventListener(RpcEvent.SUCCESS, onGetReceivedMailsSuccess);
            rm.addEventListener(RpcEvent.FAIL, onGetReceivedMailsFail);
            getReceivedMailsRpc = rm.getReceivedMails();
            rm.commit();
        }
        
        private function onGetReceivedMailsSuccess(e:Event):void {
            var mails:Array = getReceivedMailsRpc.mails;
            var auditChange:Object = new AuditChange();
            auditChange.action = AuditChangeAction.acceptFeedGiftMail;
            auditChange.mailId = [];
            var MAIL_FAN_PAGE_ITEM:uint = CPRC.RpcClient.MAIL_FAN_PAGE_ITEM;
            for each (var mail:Object in mails)
                if (mail.type == MAIL_FAN_PAGE_ITEM)
                    auditChange.mailId.push(mail.id);
            log('accepting ' + JSON.stringify(auditChange.mailId));
            
            savePlayerProfile([auditChange]);
        }
        
        private function onGetReceivedMailsFail(e:Event):void {
            throw 'get received mails fail';
        }
        
        private function fromInventoryToGame(globalItemId:Number, positionX:Number, positionY:Number, roomIndex:uint, data:Number, number:int):void {
            var auditChanges:Array = [];
            for (var i:int = 0; i < number; i++) {
                var ownedItem:Object = new CPRC.OwnedItem();
                ownedItem.id = -i;
                ownedItem.globalItemId = globalItemId;
                ownedItem.positionX = positionX;
                ownedItem.positionY = positionY;
                ownedItem.roomIndex = roomIndex;
                ownedItem.data = data;
                var auditChange:Object = new AuditChange();
                auditChange.action = AuditChangeAction.fromInventoryToGame;
                auditChange.ownedItem = ownedItem;
                auditChanges.push(auditChange);
            }
            
            savePlayerProfile(auditChanges);
        }
        
        private function fromGameToInventory(globalItemId:Number, roomIndex:uint):void {
            var auditChanges:Array = [];
            for each (var ownedItem:Object in getUserProfileRpc.userInfo.ownedItem) {
                if (ownedItem.globalItemId != globalItemId || ownedItem.roomIndex != roomIndex)
                    continue;
                var auditChange:Object = new AuditChange();
                auditChange.action = AuditChangeAction.fromGameToInventory;
                auditChange.ownedItem = ownedItem;
                auditChanges.push(auditChange);
            }
            
            savePlayerProfile(auditChanges);
        }
        
        private function sellPurchaseOwnedItem(employeeId:String, globalItemId:Number):void {
            var category:int = globalItemId > 999999 ? globalItemId / 10000 : globalItemId;
            var auditChanges:Array = [];
            var ownedItem:Object, auditChange:Object;
            var employee:Object = new NetworkUid(NetworkUid.FACEBOOK, employeeId, 0);
            
            for each (var equipped:Object in getUserProfileRpc.userInfo.ownedItem) {
                if (
                    equipped.employeeId &&
                    equipped.employeeId.networkUid == employeeId &&
                    int(equipped.globalItemId / 10000) == category
                ) {
                    ownedItem = new CPRC.OwnedItem();
                    ownedItem.globalItemId = equipped.globalItemId;
                    ownedItem.id = equipped.id;
                    ownedItem.employeeId = employee;
                    auditChange = new AuditChange();
                    auditChange.action = AuditChangeAction.sellOwnedItem;
                    auditChange.itemToken = tokenMap[equipped.globalItemId];
                    auditChange.ownedItem = ownedItem;
                    auditChanges.push(auditChange);
                    
                    log('sellOwnedItem ' + auditChange.itemToken + ' ' + ownedItem.globalItemId + ' ' + ownedItem.id + ' ' + ownedItem.employeeId.networkUid); // %%%
                }
            }
            
            if (globalItemId > 999999) {
                ownedItem = new CPRC.OwnedItem();
                ownedItem.globalItemId = globalItemId;
                ownedItem.id = -1;
                ownedItem.employeeId = employee;
                auditChange = new AuditChange();
                auditChange.action = AuditChangeAction.purchaseOwnedItem;
                auditChange.itemToken = tokenMap[globalItemId];
                auditChange.ownedItem = ownedItem;
                auditChanges.push(auditChange);
                
                log('purchaseOwnedItem ' + auditChange.itemToken + ' ' + ownedItem.globalItemId + ' ' + ownedItem.id + ' ' + ownedItem.employeeId.networkUid); // %%%
            }
            
            savePlayerProfile(auditChanges);
        }
        
        // headless
        private function getUserInfo():Object {
            return getUserProfileRpc.userInfo;
        }
        
        // headless
        private function consumeItem(itemId:int):void {
            var auditChange:Object = new AuditChange();
            auditChange.action = AuditChangeAction.consumeItem;
            auditChange.itemId = itemId;
            
            savePlayerProfile([auditChange]);
        }
        
        // headless
        private function consumeIngredients():void {
            var auditChanges:Array = [];
            var auditChange:Object;
            var ingredients:Array = getUserProfileRpc.userInfo.ingredients;
            for each (var inventoryItem:Object in ingredients) {
                for (var i:int = 0; i < inventoryItem.number; i++) {
                    auditChange = new AuditChange();
                    auditChange.action = AuditChangeAction.consumeItem;
                    auditChange.itemId = inventoryItem.globalItemId;
                    auditChanges.push(auditChange);
                }
            }
            
            savePlayerProfile(auditChanges);
        }
        
        private function today():String {
            var timestamp:Date = new Date();
            var date:Number = timestamp.dateUTC;
            var month:Number = timestamp.monthUTC + 1;
            var year:Number = timestamp.fullYearUTC;
            return (
                (date < 10 ? '0' + date : date) + '/' +
                (month < 10 ? '0' + month : month) + '/' +
                year
            );
        }
        
        private function reverseDate(d:String):String {
            return d.split('/', 3).reverse().join('/');
        }
        
        // headless
        private function autoGift():void {
            log('computing deficiency');
            var date:String = reverseDate(today());
            var list:Object = {};
            var recipeIdMap:Object = {};
            var ingredientIdMap:Object = {};
            var ingredientNameMap:Object = {};
            var combinedMap:Object = {};
            var userInfo:Object = getUserProfileRpc.userInfo;
            var item:Object;
            
            for each (item in databases['recipe']..item) {
                recipeIdMap[item.@id] = item;
                combinedMap[item.@id] = item.@name.toString();
                list[item.@id] = 10;
            }
            for each (item in databases['ingredient']..item) {
                ingredientIdMap[item.@id] = item;
                ingredientNameMap[item.@name] = item.@id.toString();
                combinedMap[item.@id] = item.@name.toString();
                list[item.@id] = 1;
            }
            
            for each (item in userInfo.ingredients) list[item.globalItemId] -= item.number;
            for each (item in userInfo.recipes) list[item.globalItemId] -= item.number;
            
            for each (item in recipeIdMap) {
                var id:String = item.@id;
                if (list[id] <= 0) {
                    delete list[id];
                } else {
                    var need:int;
                    if (list[id] == 10 && (item.@invisible.length() || (item.@expireDate.length() && reverseDate(item.@expireDate) < date))) {
                        need = 9;
                        list[id] = 1;
                    } else {
                        need = list[id];
                        delete list[id];
                    }
                    for each (var ingredientName:String in item.@ingredients.split(/\s*,\s*/)) {
                        if (!(ingredientName in ingredientNameMap)) log(item.toXMLString());
                        list[ingredientNameMap[ingredientName]] += need;
                    }
                }
            }
            
            for each (item in ingredientIdMap) if (list[item.@id] <= 0) delete list[item.@id.toString()];
            
            // %%%%%%%%% turns out this is far from ready
            var debug:Array = [];
            for (item in list) debug.push([item, combinedMap[item], list[item]]);
            debug.sortOn([2, 0]);
            for (var i:int = 0; i < debug.length; i++) debug[i] = debug[i].join('\t');
            log('you need:\n' + debug.join('\n'));
            return; // %%%
            
            log('sending mail');
            var mail:Object = new CPRC.Mail();
            mail.type = CPRC.RpcClient.MAIL_FAN_PAGE_ITEM;
            mail.message = '';
            mail.recipientId = getUserProfileRpc.userInfo.id;
            GameWorld.rpcClient.beginBatch(RpcClient.BATCHMODE_CONDITIONAL);
            var notified:Boolean = false;
            var count:int = 64;
            
            queueMessages: for (var key:String in list) {
                mail.globalItemIds = [parseInt(key, 10)];
                for (var i:int = 0; i < list[key]; i++) {
                    GameWorld.rpcClient.sendMail(mail,
                        function (e:Number):void {
                            if (!notified) setTimeout(acceptFeedGiftMail, 0);
                            notified = true;
                            if (e) log('mail sent ' + e);
                        },
                        function ():void { log('failmail'); }
                    );
                    if (!--count) break queueMessages;
                }
            }
            
            GameWorld.rpcClient.endBatch();
        }
        
    }
}

import flash.system.ApplicationDomain;
import flash.utils.Proxy;
import flash.utils.flash_proxy;

internal class DLL extends Proxy {
    
    private var prefix:String;
    
    public function DLL(prefix:String = '') {
        this.prefix = prefix;
    }
    
    override flash_proxy function getProperty(name:*):* {
        return ApplicationDomain.currentDomain.getDefinition(prefix + name);
    }
    
}