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

flash on 2013-2-10

Get Adobe Flash player
by go-space 15 Feb 2013
    Embed
/**
 * Copyright go-space ( http://wonderfl.net/user/go-space )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/p6bT
 */

package 
{
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.SharedObject;
    import flash.net.Socket;
    import flash.system.Capabilities;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.ui.Keyboard;
    import flash.utils.ByteArray;
    
    import com.bit101.components.CheckBox;
    import com.bit101.components.ComboBox;
    import com.bit101.components.NumericStepper;
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    import com.bit101.components.Text;
    
    public class BouyomiChatClient extends Sprite 
    {

        public static var stage:Stage;
        private static var nameCheck:CheckBox;
        private static var cacheByte:ByteArray;
        private static var clearButton:PushButton;
        private static var commentText:Text;
        private static var connectButton:PushButton;
        private static var ipText:Text;
        private static var nameText:Text;
        private static var portText:Text;
        private static var sharedObject:SharedObject;
        private static var socket:Socket;
        private static var twitButton:PushButton;
        private static var logTextArea:TextAreaLogCustom;
        private static var speedCheck:CheckBox;
        private static var speedNumericStepper:NumericStepper;
        private static var toneCheck:CheckBox;
        private static var toneNumericStepper:NumericStepper;
        private static var volumeCheck:CheckBox;
        private static var volumeNumericStepper:NumericStepper;
        private static var voiceComboBox:ComboBox;
        
        public function BouyomiChatClient ()
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        public static function set log (value:String):void
        {
            logTextArea.text = value;
        }
        
        private function init (event:Event = null):void 
        {
            var i:uint;
            var n:uint;
            var label:Label;
            var fmt:TextFormat;
            
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            BouyomiChatClient.stage = stage;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.HIGH;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.showDefaultContextMenu = false;
            stage.stageFocusRect = false;
            
            Style.embedFonts = false;
            Style.fontName = '_等幅';
            Style.fontSize = 10;
            
            sharedObject = SharedObject.getLocal('BouyomiClient') as SharedObject;
            
            ipText = new Text(this, 36, 50);
            fmt = ipText.textField.defaultTextFormat;
            fmt.align = TextFormatAlign.CENTER;
            ipText.textField.defaultTextFormat = fmt;
            ipText.textField.multiline = false;
            ipText.width = 100;
            ipText.height = 20;
            ipText.text = sharedObject.data.ip == undefined ? '127.0.0.1' : sharedObject.data.ip;
            label = new Label(this, 0, 53, 'IP:');
            label.x = ipText.x - label.width;

            portText = new Text(this, 190, 50);
            fmt = portText.textField.defaultTextFormat;
            fmt.align = TextFormatAlign.CENTER;
            portText.textField.defaultTextFormat = fmt;
            portText.textField.multiline = false;
            portText.width = 100;
            portText.height = 20;
            portText.text = sharedObject.data.port == undefined ? '843' : sharedObject.data.port;
            label = new Label(this, 0, 53, 'Port:');
            label.x = portText.x - label.width;
            
            connectButton = new PushButton(this, portText.x + portText.width + 20, 50, '', onConnectClick);
            
            nameText = new Text(this, 36, 100);
            fmt = nameText.textField.defaultTextFormat;
            fmt.align = TextFormatAlign.CENTER;
            nameText.textField.defaultTextFormat = fmt;
            nameText.textField.multiline = false;
            nameText.width = 100;
            nameText.height = 20;
            nameText.text = sharedObject.data.name == undefined ? '名無し' : sharedObject.data.name;
            label = new Label(this, 10, 103, '名前:');
            label.x = nameText.x - label.width;
            
            commentText = new Text(this, 190, 100);
            commentText
            commentText.width = 200;
            commentText.height = 20;
            commentText.addEventListener(KeyboardEvent.KEY_UP, onKeyup);
            label = new Label(this, nameText.x + nameText.width + 10, 103, 'コメント:');
            label.x = commentText.x - label.width;
            
            nameCheck = new CheckBox(this, 36, 150, '名乗る');
            nameCheck.selected = true;
            
            speedCheck = new CheckBox(this, 36, 180, 'デフォルスピード');
            speedCheck.selected = true;
            
            speedNumericStepper = new NumericStepper(this, 170);
            speedNumericStepper.maximum = 300;
            speedNumericStepper.minimum = 50;
            speedNumericStepper.y = speedCheck.y + speedCheck.height * 0.5 - speedNumericStepper.height * 0.5;
            
            toneCheck = new CheckBox(this, 36, 210, 'デフォルトトーン');
            toneCheck.selected = true;
            
            toneNumericStepper = new NumericStepper(this, 170);
            toneNumericStepper.maximum = 200;
            toneNumericStepper.minimum = 50;
            toneNumericStepper.y = toneCheck.y + toneCheck.height * 0.5 - toneNumericStepper.height * 0.5;
            
            volumeCheck = new CheckBox(this, 36, 240, 'デフォルトボリューム');
            volumeCheck.selected = true;
            
            volumeNumericStepper = new NumericStepper(this, 170);
            volumeNumericStepper.maximum = 200;
            volumeNumericStepper.minimum = 50;
            volumeNumericStepper.y = volumeCheck.y + volumeCheck.height * 0.5 - volumeNumericStepper.height * 0.5;
            
            voiceComboBox = new ComboBox(this, 36, 270);
            voiceComboBox.addItem( { label:'デフォルト音声' } );
            voiceComboBox.addItem( { label:'女性1' } );
            voiceComboBox.addItem( { label:'女性2' } );
            voiceComboBox.addItem( { label:'男性1' } );
            voiceComboBox.addItem( { label:'男性2' } );
            voiceComboBox.addItem( { label:'中性' } );
            voiceComboBox.addItem( { label:'ロボット' } );
            voiceComboBox.addItem( { label:'機械1' } );
            voiceComboBox.addItem( { label:'機械2' } );
            voiceComboBox.selectedIndex = 0;
            
            twitButton = new PushButton(this, voiceComboBox.x + voiceComboBox.width + 20, 270, '棒つぶやく', onTwitClick);
            
            clearButton = new PushButton(this, 0, 0, 'Clear', onClearClick);
            clearButton.x = stage.stageWidth - (clearButton.width + 10);
            clearButton.y = stage.stageHeight - clearButton.height - 10;
            
            logTextArea = new TextAreaLogCustom(this, 10, 0);
            logTextArea.width = stage.stageWidth - 20;
            logTextArea.y = clearButton.y - logTextArea.height - 10;
            
            close();
        }
        
        private function onClearClick (event:MouseEvent):void
        {
            BouyomiChatClient.log = null;
        }

        private function onConnectClick (event:MouseEvent):void
        {
            switch (connectButton.label)
            {
                case 'Connect' :
                    open();
                    break;
                
                case 'Close' :
                    close();
                    break;
            }
        }
        
        private function open ():void
        {
            close();
            cacheByte = new ByteArray();
            connectButton.enabled = false;
            connectButton.label = 'Connecting';
            socket = new Socket();
            socket.addEventListener(Event.CLOSE, onClose);
            socket.addEventListener(Event.CONNECT, onConnect);
            socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
            socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
            socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
            try
            {
                socket.connect(ipText.text, int(portText.text));
            }
            catch (error:Error)
            {
                BouyomiChatClient.log = error.message;
            }
        }
        
        private function close ():void
        {
            if (socket && socket.connected)
            {
                try
                {
                    socket.close();
                }
                catch (error:Error)
                {
                    BouyomiChatClient.log = error.message;
                }
                socket = null;
            }
            connectButton.enabled = true;
            connectButton.label = 'Connect';
            twitButton.enabled = false;
        }
        
        private function onClose (event:Event):void
        {
            BouyomiChatClient.log = '【onClose】';
            connectButton.enabled = true;
            connectButton.label = 'Connect';
            twitButton.enabled = false;
        }
        
        private function onConnect (event:Event):void
        {
            BouyomiChatClient.log = '【onConnect】';
            connectButton.enabled = true;
            connectButton.label = 'Close';
            twitButton.enabled = true;
            
            sharedObject.data.ip = ipText.text;
            sharedObject.data.port = portText.text;
        }
        
        private function onIOError (event:IOErrorEvent):void
        {
            BouyomiChatClient.log = '【onIOError】';
            close();
        }
        
        private function onSocketData (event:ProgressEvent):void
        {
            // BouyomiChatClient.log = 'onSocketData';
            socket.readBytes(cacheByte, cacheByte.length, socket.bytesAvailable);
            parseData();
        }
        
        private function onSecurityError (event:SecurityErrorEvent):void
        {
            BouyomiChatClient.log = '【onSecurityError】';
            close();
        }
        
        private function parseData ():void
        {
            var str:String;
            var pattern:RegExp = /^hdr:([0-9]+?)\n/;
            var result:Object;
            var headerLength:uint;
            var contentLength:uint;
            var headerByte:ByteArray;
            var bodyByte:ByteArray;
            var remainder:ByteArray;
            
            // ヘッダから容量を取得
            cacheByte.position = 0;
            str = cacheByte.readUTFBytes(cacheByte.bytesAvailable);
            result = pattern.exec(str);
            if (!result)
            {
                // パターンにマッチしない
                return;
            }
            else
            {
                // パターンにマッチした
                contentLength = uint(result[1]);
            }
            
            // ヘッダを再現し長さを取得
            headerByte = new ByteArray();
            headerByte.writeUTFBytes('hdr:' + String(contentLength) + '\n');
            headerLength = headerByte.length;
            
            // キャッシュがヘッダ容量+コンテンツ容量を上回るか?
            if (cacheByte.length < headerLength + contentLength)
            {
                trace('容量を下回っている' + cacheByte.length + '<' + (headerLength + contentLength));
                return;
            }
            else
            {
                // 上回っているので、ボディの最初へポインタの位置を移動する
                cacheByte.position = headerByte.length;
            }
            
            // ボディを生成
            bodyByte = new ByteArray();
            cacheByte.readBytes(bodyByte, 0, contentLength);
            parseBody(bodyByte);
            //trace(MZTool.print_r(bodyByte.readObject()));
            
            // 余りを生成
            remainder = new ByteArray();
            remainder.writeBytes(cacheByte, headerLength + contentLength, cacheByte.bytesAvailable);
            
            // 余りをキャッシュに書き込む
            cacheByte.length = 0;
            cacheByte.writeBytes(remainder, 0, remainder.bytesAvailable);
            
            // キャッシュがあればもう一回パースする
            if (cacheByte.length > 0)
            {
                parseData();
            }
        }
        
        private function parseBody (bodyByte:ByteArray):void
        {
            var obj:Object = bodyByte.readObject();
            var name:String = obj.name ? obj.name : 'unknown';
            var comment:String = obj.comment ? obj.comment : '・・・';
            
            BouyomiChatClient.log = name + 'さん:' + comment;
        }
        
        private function onKeyup (event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.ENTER)
                twit();
        }
        
        private function onTwitClick (event:Event):void
        {
            twit();
        }
        
        private function twit ():void
        {
            var bodyByte:ByteArray;
            var contentLength:uint;
            var headerByte:ByteArray;
            var speed:int = speedCheck.selected ? -1 : speedNumericStepper.value;
            var tone:int = toneCheck.selected ? -1 : toneNumericStepper.value;
            var volume:int = volumeNumericStepper.value;
            var voice:uint = voiceComboBox.selectedIndex;
            /*
            name:名前
            comment:コメント
            speed:速度(-1:デフォルト, 50~300)
            tone:音程(-1:デフォルト, 50~200)
            volume:音量(-1:デフォルト,  0~100)
            voice:声質(0:棒読みちゃん画面上の設定、1:女性1、2:女性2、3:男性1、4:男性2、5:中性、6:ロボット、7:機械1、8:機械2、10001~:SAPI5)
            */
            if (commentText.text != '' && socket && socket.connected)
            {
                bodyByte = new ByteArray();
                bodyByte.writeObject( {
                    isName:nameCheck.selected,
                    name:nameText.text,
                    comment:commentText.text,
                    speed:speed,
                    tone:tone,
                    volume:volume,
                    voice:voice
                } );
                contentLength = bodyByte.length;
                                
                headerByte = new ByteArray();
                headerByte.writeUTFBytes('hdr:' + String(contentLength) + '\n');
                
                socket.writeBytes(headerByte, 0, headerByte.length);
                socket.writeBytes(bodyByte, 0, bodyByte.length);
                socket.flush();
                commentText.text = '';

            }
        }
    }
}

import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.text.TextField;
import com.bit101.components.TextArea;
import com.bit101.components.VScrollBar;

class TextAreaLogCustom extends TextArea
{
    public function TextAreaLogCustom (parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, text:String = '')
    {
        super(parent, xpos, ypos, text);
    }
    
    override public function set text (t:String):void
    {
        if (_text != '')
        {
            _text += '\n' + t;
        }
        else
        {
            _text += t;
        }
        
        if (t == null)
            _text = "";
        
        invalidate();
    }
    
    public function get tf ():TextField
    {
        return _tf;
    }
    
    public function get scrollbar ():VScrollBar
    {
        return _scrollbar;
    }
    
    override public function draw ():void
    {
        super.draw();
        _tf.width = _width - _scrollbar.width - 4;
        _scrollbar.x = _width - _scrollbar.width;
        _scrollbar.height = _height;
        _scrollbar.draw();
        addEventListener(Event.ENTER_FRAME, onTextScrollDelay);
        _tf.scrollV = _tf.maxScrollV;
    }
}