Exemple #1
0
        private void ReplaceRsaKeys(ShockwaveFlash flash)
        {
            foreach (IFlashTag flashTag in _flash.Tags)
            {
                if (flashTag.Header.Tag != FlashTagType.DefineBinaryData)
                {
                    continue;
                }

                var    binaryDataTag = (DefineBinaryDataTag)flashTag;
                string binaryData    = Encoding.UTF8.GetString(binaryDataTag.Data);
                if (binaryData.Contains("habbo_login_dialog"))
                {
                    string extractedRsaKeys = binaryData.GetChild("name=\"dummy_field\" caption=\"", '"');
                    DecodeRsaKeys(extractedRsaKeys);

                    string generatedRsaKeys = EncodeRsaKeys(Main.FAKE_EXPONENT, Main.FAKE_MODULUS);
                    binaryData         = binaryData.Replace(extractedRsaKeys, generatedRsaKeys);
                    binaryDataTag.Data = Encoding.UTF8.GetBytes(binaryData);

                    flash.Compile();
                    break;
                }
            }
        }
Exemple #2
0
        static byte[] Compress(ShockwaveFlash flash)
        {
            WriteLine("Compressing... | ({0}MB) | This may take a while, no more than a minute, hopefully.",
                      (((int)flash.FileLength / 1024) / 1024));

            return(flash.Compress());
        }
Exemple #3
0
        private void ReplaceKeys(ShockwaveFlash flash)
        {
            foreach (IFlashTag flashTag in _flash.Tags)
            {
                if (flashTag.Header.Tag != FlashTagType.DefineBinaryData)
                {
                    continue;
                }

                var    binTag = (DefineBinaryDataTag)flashTag;
                string binDat = _encoding.GetString(binTag.Data);
                if (binDat.Contains("habbo_login_dialog"))
                {
                    const string dummyFieldPrefix = "name=\"dummy_field\" caption=\"";
                    string       encodedKeys      = binDat.GetChild(dummyFieldPrefix, '"');
                    ExtractRSAKeys(encodedKeys);

                    string encodedFakeKeys = EncodeRSAKeys(_main.RsaKeys[0][0], _main.RsaKeys[0][1]);
                    binDat = binDat.Replace(encodedKeys, encodedFakeKeys);

                    binTag.Data = _encoding.GetBytes(binDat);
                    flash.Compile();
                    break;
                }
            }
        }
Exemple #4
0
        private void VideoOnline_Load(object sender, EventArgs e)
        {
            //sustituye una parte de la url de youtube para poder reproducirla en la aplicacion
            string videoUrl = _url.Replace("watch?v=", "v/");

            ShockwaveFlash.Movie = videoUrl;
            ShockwaveFlash.Play();
        }
        public UnsupportedTag(ShockwaveFlash flash, RecordHeader header, bool forceLong = false)
        {
            _flash     = flash;
            _forceLong = forceLong;

            Header   = header;
            Position = _flash.Position;

            Data = _flash.ReadUI8Block((int)header.Length);
        }
        public byte[] ToBytes()
        {
            var buffer = new List <byte>(Data.Length + 6);

            buffer.AddRange(BitConverter.GetBytes(CharacterId));
            buffer.AddRange(BitConverter.GetBytes(Reserved));
            buffer.AddRange(Data);

            return(ShockwaveFlash.ConstructTagData(Header.Tag, buffer.ToArray()));
        }
        public DefineBinaryDataTag(ShockwaveFlash flash, RecordHeader header)
        {
            _flash = flash;

            Position = flash.Position;
            Header   = header;

            CharacterId = _flash.ReadUI16();
            Reserved    = _flash.ReadUI32();
            _data       = _flash.ReadUI8Block((int)header.Length - 6);
        }
Exemple #8
0
        static byte[] Compress(ShockwaveFlash flash)
        {
            int uncompressedSizeMB = (((int)flash.FileLength / 1024) / 1024);

            Console.Write($"Compressing... | ({uncompressedSizeMB}MB)");

            byte[] compressedData   = flash.Compress();
            int    compressedSizeMB = ((compressedData.Length / 1024) / 1024);

            WriteLine($" -> ({compressedSizeMB}MB)");
            return(compressedData);
        }
Exemple #9
0
        static bool Decompress(ShockwaveFlash flash)
        {
            if (flash.Compression != CompressionType.None)
            {
                Console.Clear();
                int compressedSizeMB   = ((flash.ToByteArray().Length / 1024) / 1024);
                int uncompressedSizeMB = (((int)flash.FileLength / 1024) / 1024);

                Console.Write($"Decompressing... | ({compressedSizeMB}MB)");
                flash.Decompress();
                WriteLine($" -> ({uncompressedSizeMB}MB)");
            }
            return(!flash.IsCompressed);
        }
Exemple #10
0
        static bool Decompress(ShockwaveFlash flash)
        {
            if (flash.CompressWith != CompressionStandard.None)
            {
                int compressedSizeMB   = ((flash.ToArray().Length / 1024) / 1024);
                int uncompressedSizeMB = (((int)flash.FileLength / 1024) / 1024);

                ClearWriteLine("Decompressing... | ({0}MB) -> ({1}MB)",
                               compressedSizeMB, uncompressedSizeMB);

                flash.Decompress();
            }
            return(!flash.IsCompressed);
        }
Exemple #11
0
        public void DisposeViewModel()
        {
            //ウェブブラウザ開放
            DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => {
                //UIスレッドじゃないとAccessViolationになる時がある
                ShockwaveFlash.Dispose();
                VideoFlash           = null;
                Controller           = null;
                FullScreenVideoFlash = null;
                FullScreenContoller  = null;

                App.ViewModelRoot.RemoveTabAndLastSet(this);
                Dispose();
            }));
        }
Exemple #12
0
        private void LoadGameClient(string path)
        {
            if (InvokeRequired)
            {
                Invoke(_loadGameClient, path); return;
            }

            try { _flash = new ShockwaveFlash(path); }
            catch { path = string.Empty; }
            finally
            {
                UseCustomClient      = (_flash != null && !_flash.IsCompressed);
                CustomClientTxt.Text = path;
            }
        }
Exemple #13
0
        public Rect(ShockwaveFlash flash)
        {
            int pos   = flash.Position;
            int nBits = (int)flash.ReadUB(5);

            _x          = flash.ReadSB(nBits);
            _twipsWidth = flash.ReadSB(nBits);
            _width      = _twipsWidth / 20;

            _y           = flash.ReadSB(nBits);
            _twipsHeight = flash.ReadSB(nBits);
            _height      = _twipsHeight / 20;

            _data = flash.ReadUI8Block(flash.Position - pos, pos);
        }
Exemple #14
0
        private async Task <bool> VerifyGameClientAsync(ShockwaveFlash flash)
        {
            if (flash.IsCompressed)
            {
                StatusTxt.SetDotAnimation("Decompressing Client");
                bool decompressed = await flash.DecompressAsync()
                                    .ConfigureAwait(false);
            }

            if (!flash.IsCompressed)
            {
                MainUI.Game = flash;
            }

            return(MainUI.Game != null);
        }
Exemple #15
0
        private void ProcessSwf(string path)
        {
            if (InvokeRequired)
            {
                Invoke(_processSwf, path); return;
            }

            CustomClientTxt.Text = path;
            Cursor = Cursors.WaitCursor;
            try
            {
                _flash = new ShockwaveFlash(path);
            }
            catch
            {
                _flash = null;
                CustomChckbx.Checked = false;
                CustomClientTxt.Text = string.Empty;
            }
            UseCustomClient = (_flash != null && !_flash.IsCompressed);
            Cursor          = Cursors.Default;
        }
Exemple #16
0
 public byte[] ToBytes()
 {
     return(ShockwaveFlash.ConstructTagData(Header.Tag, Data, _forceLong));
 }
Exemple #17
0
        private byte[] ProcessResponse(byte[] payload, bool isFlash)
        {
            if (UseCustomClient && isFlash && payload.Length > 3000000)
            {
                if (!_replaceKeys)
                {
                    payload = _flash.ToBytes();
                }
                else
                {
                    _flash = new ShockwaveFlash(payload);

                    ReplaceRsaKeys(_flash);
                    payload = _flash.ToBytes();

                    string clientPath = Path.Combine("Patched Clients", GameData.FlashClientBuild + ".swf");
                    Task.Factory.StartNew(() => _flash.Save(clientPath, true));
                }

                FiddlerApplication.Shutdown();
                StatusTxt.BeginAnimation("Connecting{0} | Port: " + GameData.Port, "...");
                return(payload);
            }
            else if (TanjiMode.IsManual)
            {
                return(payload);
            }

            string response = Encoding.UTF8.GetString(payload);

            if (response.Contains("connection.info.host") && response.Contains("connection.info.port"))
            {
                GameData = HGameData.Parse(response);
                if (!UseCustomClient)
                {
                    string patchedClientPath = Path.Combine("Patched Clients", GameData.FlashClientBuild + ".swf");

                    if (!File.Exists(patchedClientPath))
                    {
                        UseCustomClient = _replaceKeys = true;
                    }
                    else
                    {
                        LoadGameClient(patchedClientPath);
                    }
                }

                if (!UseCustomClient)
                {
                    FiddlerApplication.Shutdown();
                    StatusTxt.BeginAnimation("Connecting{0} | Port: " + GameData.Port, "...");
                }
                else if (_replaceKeys)
                {
                    StatusTxt.BeginAnimation("Modifying Client{0}", "...");
                }
                else
                {
                    StatusTxt.BeginAnimation("Replacing Client{0}", "...");
                }

                _main.Game.Connect(true, GameData.Host, GameData.Port);

                response = response.Replace("/Habbo.swf", "/Habbo.swf?" + _numberGenerator.Next());
                payload  = Encoding.UTF8.GetBytes(response);
            }
            return(payload);
        }
Exemple #18
0
        public static void Parse()
        {
            if (Parts == null)
            {
                Parts = new Dictionary <string, FigureDocument>();
            }


            if (Parts.Count == 0 && Directory.GetDirectories("figuredata/compiled").Length > 1)
            {
                foreach (var file in Directory.GetFiles("figuredata/compiled"))
                {
                    string fileName = Path.GetFileNameWithoutExtension(file);
                    ParseXML(fileName, file);
                }
            }

            foreach (var file in Directory.GetFiles("figuredata/compiled"))
            {
                string fileName = Path.GetFileNameWithoutExtension(file);

                //if (Directory.Exists(@"furni_export\" + fileName))
                //    return false;


                if (!Directory.Exists(@"figuredata/" + fileName))
                {
                    Directory.CreateDirectory(@"figuredata/" + fileName);
                }

                var flash = new ShockwaveFlash(file);
                flash.Disassemble();

                if (!Directory.Exists(@"figuredata/" + fileName + "/xml"))
                {
                    Directory.CreateDirectory(@"figuredata/" + fileName + "/xml");
                }

                var symbolClass = flash.Tags.Where(t => t.Kind == TagKind.SymbolClass).Cast <SymbolClassTag>().First();
                var imageTags   = flash.Tags.Where(t => t.Kind == TagKind.DefineBitsLossless2).Cast <DefineBitsLossless2Tag>();
                var dataTags    = flash.Tags.Where(t => t.Kind == TagKind.DefineBinaryData).Cast <DefineBinaryDataTag>();

                foreach (var data in dataTags)
                {
                    var name = symbolClass.Names[symbolClass.Ids.IndexOf(data.Id)];
                    var type = name.Split('_')[name.Split('_').Length - 1];
                    var txt  = Encoding.Default.GetString(data.Data);

                    if (!File.Exists(@"figuredata/" + fileName + "/xml/" + type + ".xml"))
                    {
                        File.WriteAllText(@"figuredata/" + fileName + "/xml/" + type + ".xml", txt);
                    }
                }

                var symbolsImages = new Dictionary <int, DefineBitsLossless2Tag>();

                foreach (var image in imageTags)
                {
                    symbolsImages[image.Id] = image;
                }

                foreach (var symbol in symbolClass.Names)
                {
                    //Console.WriteLine(symbolClass.Names.IndexOf(symbol) + " / " + symbol + " / " + symbolClass.Ids[symbolClass.Names.IndexOf(symbol)]);

                    int symbolId = symbolClass.Ids[symbolClass.Names.IndexOf(symbol)];

                    if (!symbolsImages.ContainsKey(symbolId))
                    {
                        continue;
                    }

                    string name = symbol;

                    var image   = symbolsImages[symbolId];
                    var xmlName = name.Substring(fileName.Length + 1);

                    WriteImage(image, @"figuredata/" + fileName + "/" + xmlName + ".png");
                }

                ParseXML(fileName, file);
            }
        }
Exemple #19
0
        public static bool Parse(string file)
        {
            string fileName = Path.GetFileNameWithoutExtension(file);

            var flash = new ShockwaveFlash(file);

            flash.Disassemble();


            if (!Directory.Exists(@"furni_export/" + fileName))
            {
                Directory.CreateDirectory(@"furni_export/" + fileName);
            }

            if (!Directory.Exists(@"furni_export/" + fileName + "/xml"))
            {
                Directory.CreateDirectory(@"furni_export/" + fileName + "/xml");
            }

            var symbolClass = flash.Tags.Where(t => t.Kind == TagKind.SymbolClass).Cast <SymbolClassTag>().First();
            var imageTags   = flash.Tags.Where(t => t.Kind == TagKind.DefineBitsLossless2).Cast <DefineBitsLossless2Tag>();
            var dataTags    = flash.Tags.Where(t => t.Kind == TagKind.DefineBinaryData).Cast <DefineBinaryDataTag>();

            foreach (var data in dataTags)
            {
                var name = symbolClass.Names[symbolClass.Ids.IndexOf(data.Id)];
                var type = name.Split('_')[name.Split('_').Length - 1];
                var txt  = Encoding.Default.GetString(data.Data);

                if (!File.Exists(@"furni_export/" + fileName + "/xml/" + type + ".xml"))
                {
                    File.WriteAllText(@"furni_export/" + fileName + "/xml/" + type + ".xml", txt);
                }
            }

            var assetDocument = FileUtil.SolveXmlFile(@"furni_export/" + fileName + "/xml", "assets");
            var assets        = assetDocument.SelectNodes("//assets/asset");

            var symbolsImages = new Dictionary <int, DefineBitsLossless2Tag>();

            foreach (var image in imageTags)
            {
                symbolsImages[image.Id] = image;
            }

            foreach (var symbol in symbolClass.Names)
            {
                //Console.WriteLine(symbolClass.Names.IndexOf(symbol) + " / " + symbol + " / " + symbolClass.Ids[symbolClass.Names.IndexOf(symbol)]);

                int symbolId = symbolClass.Ids[symbolClass.Names.IndexOf(symbol)];

                if (!symbolsImages.ContainsKey(symbolId))
                {
                    continue;
                }

                string name = symbol;

                var image   = symbolsImages[symbolId];
                var xmlName = name.Substring(fileName.Length + 1);

                WriteImage(image, @"furni_export/" + fileName + "/" + xmlName + ".png");
            }

            for (int i = 0; i < assets.Count; i++)
            {
                var asset = assets.Item(i);

                if (asset.Attributes.GetNamedItem("source") == null)
                {
                    continue;
                }

                var source = asset.Attributes.GetNamedItem("source").InnerText;
                var image  = asset.Attributes.GetNamedItem("name").InnerText;

                var assetImage = FileUtil.SolveFile(@"furni_export/" + fileName, source);

                var newName = image + ".png";
                var newPath = Path.Combine(@"furni_export", fileName, newName);

                if (assetImage != null)
                {
                    if (!File.Exists(newPath))
                    {
                        File.Copy(assetImage, newPath);

                        if (asset.Attributes.GetNamedItem("flipH") != null &&
                            asset.Attributes.GetNamedItem("flipH").InnerText == "1")
                        {
                            var bitmap1 = (Bitmap)Bitmap.FromFile(newPath);
                            bitmap1.RotateFlip(RotateFlipType.Rotate180FlipY);
                            bitmap1.Save(newPath);
                            bitmap1.Dispose();
                        }
                    }
                }
            }

            return(true);
        }
Exemple #20
0
        private void Eavesdropper_OnEavesResponse(object sender, EavesResponseEventArgs e)
        {
            if (UseCustomClient && e.IsSwf && e.ResponeData.Length > 3000000)
            {
                if (!_replaceKeys)
                {
                    e.ResponeData = _flash.ToBytes();
                }
                else
                {
                    _flash = new ShockwaveFlash(e.ResponeData);
                    ReplaceKeys(_flash);
                    e.ResponeData = _flash.ToBytes();

                    string clientPath = PatchedClientsDirectory + "\\" + FlashClientRevision + ".swf";
                    Task.Factory.StartNew(() => _flash.Save(clientPath, true));
                }
                Eavesdropper.Terminate();
                return;
            }
            else if (TanjiMode == TanjiMode.Manual)
            {
                return;
            }

            string response = _encoding.GetString(e.ResponeData);

            if (response.Contains(InfoHost) && response.Contains(InfoPort))
            {
                IsOriginal = SKore.IsOriginal(e.Host);

                string flashVars = response.GetChild("var flashvars", '}');
                while (!flashVars.Contains(InfoHost) || !flashVars.Contains(InfoPort))
                {
                    flashVars = flashVars.GetChild("var flashvars = {", '}');
                }

                string extractedHost = flashVars.GetChild(InfoHost, ',').Trim();
                string extractedPort = flashVars.GetChild(InfoPort, ',').Trim();

                #region Extract 'connection.info.host'
                if (string.IsNullOrEmpty(_maskHost))
                {
                    if (!extractedHost.StartsWith("\""))
                    {
                        PromptEavesdropperReset(HostExtractFail, Main.TanjiError, MessageBoxIcon.Error);
                        return;
                    }
                    else
                    {
                        _maskHost = extractedHost.Split('"')[1];
                    }
                }
                #endregion
                #region Extract 'connection.info.port'
                if (_maskPort == 0)
                {
                    if (!extractedPort.StartsWith("\""))
                    {
                        PromptEavesdropperReset(PortExtractFail, Main.TanjiError, MessageBoxIcon.Error);
                        return;
                    }
                    else
                    {
                        _maskPort = ushort.Parse(extractedPort.Split(',')[0].Split('"')[1]);
                    }
                }
                #endregion
                #region Extract 'hotelview.banner.url'
                if (!IsOriginal && response.Contains(HotelViewBannerUrl))
                {
                    Main.Cookies   = e.RawCookies;
                    Main.UserAgent = e.UserAgent;
                    Main.BannerUrl = response.GetChild(HotelViewBannerUrl, ',');
                    if (Main.BannerUrl.StartsWith("\""))
                    {
                        Main.BannerUrl = Main.BannerUrl.Split('"')[1] + "?token=";
                    }
                    if (Main.BannerUrl.StartsWith("//"))
                    {
                        Main.BannerUrl = "http://" + Main.BannerUrl;
                    }
                }
                #endregion

                if (!IsOriginal)
                {
                    response      = response.Replace(string.Format("{0}{1},", InfoHost, extractedHost), InfoHost + "\"127.0.0.1\",");
                    e.ResponeData = _encoding.GetBytes(response);
                }
                else if (!UseCustomClient)
                {
                    FlashClientRevision = ("http://" + response.GetChild(FlashClientUrl, ',').Split('"')[1].Substring(3)).Split('/')[4];
                    string patchedClientPath = PatchedClientsDirectory + "\\" + FlashClientRevision + ".swf";

                    if (!File.Exists(patchedClientPath))
                    {
                        UseCustomClient = _replaceKeys = true;
                    }
                    else
                    {
                        Invoke(new MethodInvoker(() => ProcessSwf(patchedClientPath)));
                    }
                }

                if (!UseCustomClient)
                {
                    Eavesdropper.Terminate();
                }
                SetAnimation("Connecting% | Port: " + _maskPort);

                Main.Game            = new HConnection(_maskHost, _maskPort);
                Main.Game.Connected += Game_Connected;
                Main.Game.Connect(IsOriginal);
            }
        }
Exemple #21
0
        public void Initialize()
        {
            DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => {
                if (IsFullScreen)
                {
                    FullScreenVideoFlash = new VideoFlash()
                    {
                        DataContext = this
                    };
                    FullScreenContoller = new VideoController()
                    {
                        DataContext = this
                    };
                }
                else
                {
                    VideoFlash = new VideoFlash()
                    {
                        DataContext = this
                    };
                    Controller = new VideoController()
                    {
                        DataContext = this
                    };
                }
            }));

            var videoUrl = VideoUrl + "?watch_harmful=1";


            IsActive = true;
            Task.Run(() => {
                Mylist    = new VideoMylistViewModel(this);
                Comment   = new VideoCommentViewModel(this);
                VideoData = new VideoData();


                Status = "動画情報取得中";
                //動画情報取得
                WatchApi          = new NicoNicoWatchApi(videoUrl, this);
                VideoData.ApiData = WatchApi.GetWatchApiData();

                //ロードに失敗したら
                if (VideoData.ApiData == null)
                {
                    LoadFailed = true;
                    IsActive   = false;
                    Status     = "動画の読み込みに失敗しました。";
                    return;
                }

                //有料動画なら
                if (VideoData.ApiData.IsPaidVideo)
                {
                    App.ViewModelRoot.Messenger.Raise(new TransitionMessage(typeof(PaidVideoDialog), this, TransitionMode.Modal));
                    return;
                }

                DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => {
                    if (VideoData.ApiData.Cmsid.Contains("nm"))
                    {
                        VideoData.VideoType = NicoNicoVideoType.SWF;
                        ShockwaveFlash.LoadMovie(0, GetNMPlayerPath());
                    }
                    else if (VideoData.ApiData.GetFlv.VideoUrl.StartsWith("rtmp"))
                    {
                        VideoData.VideoType = NicoNicoVideoType.RTMP;
                        ShockwaveFlash.LoadMovie(0, GetRTMPPlayerPath());
                    }
                    else
                    {
                        if (VideoData.ApiData.MovieType == "flv")
                        {
                            VideoData.VideoType = NicoNicoVideoType.FLV;
                        }
                        else
                        {
                            VideoData.VideoType = NicoNicoVideoType.MP4;
                        }
                        ShockwaveFlash.LoadMovie(0, GetPlayerPath());
                    }
                    Proxy.ExternalInterfaceCall += new ExternalInterfaceCallEventHandler(ExternalInterfaceHandler);
                    IsActive = false;

                    Task.Run(() => {
                        OpenVideo();
                    });
                }));
                Time = new VideoTime();
                //動画時間
                Time.VideoTimeString = NicoNicoUtil.ConvertTime(VideoData.ApiData.Length);

                if (VideoData.ApiData.GetFlv.IsPremium && !VideoData.ApiData.GetFlv.VideoUrl.StartsWith("rtmp"))
                {
                    Task.Run(() => {
                        StoryBoardStatus = "取得中";

                        var sb = new NicoNicoStoryBoard(VideoData.ApiData.GetFlv.VideoUrl);
                        VideoData.StoryBoardData = sb.GetStoryBoardData();

                        if (VideoData.StoryBoardData == null)
                        {
                            StoryBoardStatus = "データ無し";
                        }
                        else
                        {
                            StoryBoardStatus = "取得完了";
                        }
                    });
                }
                else
                {
                    StoryBoardStatus = "データ無し";
                }

                CommentInstance = new NicoNicoComment(VideoData.ApiData, this);
                var list        = CommentInstance.GetComment();
                if (list != null)
                {
                    foreach (var entry in list)
                    {
                        VideoData.CommentData.Add(new CommentEntryViewModel(entry));
                    }
                    dynamic json = new DynamicJson();
                    json.array   = list;

                    InjectComment(json.ToString());
                    Comment.CanComment = true;

                    //投稿者コメントがあったら取得する
                    if (VideoData.ApiData.HasOwnerThread)
                    {
                        var ulist     = CommentInstance.GetUploaderComment();
                        dynamic ujson = new DynamicJson();
                        json.array    = ulist;

                        InjectUploaderComment(json.ToString());
                    }

                    //コメント設定を反映
                    ApplyChanges();
                }

                if (!Properties.Settings.Default.CommentVisibility)
                {
                    InvokeScript("AsToggleComment");
                }
                else
                {
                    CommentVisibility = true;
                }
            });
        }
Exemple #22
0
        static void Main(string[] args)
        {
            var files = Directory.EnumerateFiles(@"Z:\furni");

            foreach (var file in files)
            {
                try
                {
                    var flash = new ShockwaveFlash(file);
                    flash.Disassemble();

                    var symbolClass = flash.Tags.Where(t => t.Kind == TagKind.SymbolClass).Cast <SymbolClassTag>().First();
                    var imageTags   = flash.Tags.Where(t => t.Kind == TagKind.DefineBitsLossless2).Cast <DefineBitsLossless2Tag>();
                    var dataTags    = flash.Tags.Where(t => t.Kind == TagKind.DefineBinaryData).Cast <DefineBinaryDataTag>();

                    var furni = new Json.JsonFurniData();
                    furni.visualization = new Json.Visualizations();
                    furni.logic         = new Json.Logic();
                    furni.assets        = new Dictionary <string, Json.Asset>();

                    foreach (var data in dataTags)
                    {
                        var name = symbolClass.Names[symbolClass.Ids.IndexOf(data.Id)];
                        var type = name.Split('_')[name.Split('_').Length - 1];
                        var txt  = Encoding.Default.GetString(data.Data);

                        var xml = new XmlDocument();
                        xml.LoadXml(txt);
                        dynamic x = JsonConvert.DeserializeObject(JsonConvert.SerializeXmlNode(xml.DocumentElement));

                        switch (type)
                        {
                        case "index":
                            furni.type = x.@object["@type"];
                            furni.visualization.type = x.@object["@visualization"];
                            furni.logic.type         = x.@object["@logic"];
                            break;

                        case "logic":
                            furni.logic.directions = new List <string>();
                            furni.logic.dimensions = new Dictionary <string, string>();

                            foreach (var dir in x.objectData.model.directions.direction)
                            {
                                furni.logic.directions.Add("" + dir["@id"]);
                            }
                            foreach (var dim in x.objectData.model.dimensions)
                            {
                                furni.logic.dimensions.Add(dim.Name.Replace("@", ""), "" + dim.Value);
                            }
                            break;

                        case "assets":
                            foreach (var asset in x.assets.asset)
                            {
                                var jAsset = new Json.Asset()
                                {
                                    name = asset["@name"], x = asset["@x"], y = asset["@y"]
                                };
                                if (asset["@flipH"] != null)
                                {
                                    jAsset.flipH = asset["@flipH"];
                                }
                                if (asset["@source"] != null)
                                {
                                    jAsset.source = asset["@source"];
                                }
                                furni.assets.Add((string)asset["@name"], jAsset);
                            }
                            break;

                        case "visualization":
                            JObject       z          = x.visualizationData;
                            XmlSerializer serializer = null;
                            serializer = new XmlSerializer(typeof(Xml.VisualizationData));

                            using (TextReader reader = new StreamReader(new MemoryStream(data.Data), Encoding.Default))
                            {
                                Xml.VisualizationData result = new Xml.VisualizationData();

                                if (z["graphics"] != null)
                                {
                                    var deser = (Xml.VisualizationData)serializer.Deserialize(reader);
                                    result.Type           = deser.Type;
                                    result.Visualizations = deser.Graphics.Visualizations;
                                }
                                else
                                {
                                    result = (Xml.VisualizationData)serializer.Deserialize(reader);
                                }

                                foreach (var viz in result.Visualizations)
                                {
                                    var jViz = new Json.Visualization();
                                    jViz.layers     = new List <Json.Layer>();
                                    jViz.directions = new Dictionary <string, List <string> >();
                                    jViz.colors     = new Dictionary <string, List <Json.Color> >();

                                    jViz.size       = "" + viz.Size;
                                    jViz.layerCount = "" + viz.LayerCount;
                                    jViz.angle      = "" + viz.Angle;
                                    foreach (var lay in viz.Layers)
                                    {
                                        jViz.layers.Add(new Json.Layer()
                                        {
                                            id = "" + lay.Id,
                                            z  = "" + lay.Z
                                        });
                                    }

                                    foreach (var dir in viz.Directions)
                                    {
                                        jViz.directions.Add("" + dir.Id, new List <string>());
                                    }

                                    foreach (var col in viz.Colors)
                                    {
                                        var color = new List <Json.Color>()
                                        {
                                            new Json.Color()
                                            {
                                                layerId = col.ColorLayer.Id, color = col.ColorLayer.Color
                                            }
                                        };
                                        jViz.colors.Add("" + col.Id, color);
                                    }

                                    switch (viz.Size)
                                    {
                                    case 1:
                                        furni.visualization.Size1 = jViz;
                                        break;

                                    case 32:
                                        furni.visualization.Size32 = jViz;
                                        break;

                                    case 64:
                                        furni.visualization.Size64 = jViz;
                                        break;
                                    }
                                }
                            }
                            break;
                        }
                    }

                    Directory.CreateDirectory(@"Z:\furni\" + furni.type);

                    foreach (var image in imageTags)
                    {
                        var name = symbolClass.Names[symbolClass.Ids.IndexOf(image.Id)];
                        Color[,] table = image.GetARGBMap();

                        int width  = table.GetLength(0);
                        int height = table.GetLength(1);
                        using (var asset = new Image <Rgba32>(width, height))
                        {
                            for (int y = 0; y < height; y++)
                            {
                                for (int x = 0; x < width; x++)
                                {
                                    Color pixel = table[x, y];
                                    asset[x, y] = new Rgba32(pixel.R, pixel.G, pixel.B, pixel.A);
                                }
                            }

                            name = name.Replace(furni.type + "_" + furni.type, furni.type);

                            using (var output = new StreamWriter(@"Z:\furni\" + furni.type + "\\" + name + ".png"))
                            {
                                asset.SaveAsPng(output.BaseStream);
                            }
                        }
                    }


                    var json = JsonConvert.SerializeObject(furni);
                    File.WriteAllText(@"Z:\furni\" + furni.type + "\\furni.json", json);
                    //Console.WriteLine(furni.type);
                }
                catch { }
            }
        }