/// <summary> /// 艦船画像を swf ファイルから読み込みます。 /// </summary> /// <param name="resourceName">艦船のリソース名(ファイル名)。</param> /// <param name="characterID">描画する画像の CharacterID 。</param> /// <returns>成功した場合は対象の Bitmap オブジェクト、失敗した場合は null を返します。</returns> public static Bitmap GetShipSwfImage(string resourceName, int characterID) { try { string shipSwfPath = GetShipResourcePath(resourceName); if (shipSwfPath != null) { var shipSwf = new SwfParser(); shipSwf.Parse(shipSwfPath); var imgtag = shipSwf.FindTags <SwfExtractor.Tags.ImageTag>().FirstOrDefault(t => t.CharacterID == characterID); return(imgtag.ExtractImage()); } return(null); } catch (Exception) { return(null); } }
private void frmMain_DragDrop(object sender, DragEventArgs e) { bool fail = false; txtLog.Text = null; foreach (string file in (string[])e.Data.GetData(DataFormats.FileDrop)) { FileInfo fi = new FileInfo(file); byte[] data = File.ReadAllBytes(file); SwfParser swf = new SwfParser(); try { swf.Parse(data); } catch { Log($"->{fi.Name} 不是有效的 SWF 文件 (Invalid SWF)"); continue; } try { DefineBinaryData payloadTag = swf.FindTags <DefineBinaryData>().ToList().Find(i => i.CharacterID == 7); byte[] payload = payloadTag.ExtractData(); byte[] decrypted = MochiDecrypt.Decrypt(payload); File.WriteAllBytes($"{fi.DirectoryName}\\{Path.GetFileNameWithoutExtension(fi.Name)}_Unpacked.swf", decrypted); Log($"->{fi.Name} 解密成功 (Success)"); } catch { Log($"->{fi.Name} 解密失败 (Failed)"); fail = true; continue; } } if (fail) { Log($"\r\n存在解密失败的文件, 可能不是 MochiCrypt 加密的文件, 或 MochiCrypt 版本有更新"); } }
private void TabExtract_DragDrop(object sender, DragEventArgs e) { bool mapAnalysis = false; string filename = ((string[])e.Data.GetData(DataFormats.FileDrop))[0]; try { SwfParser swf = new SwfParser(); swf.Parse(filename); foreach (var img in swf.FindTags <ImageTag>()) { img.ExtractImage().Save(img.CharacterID + ".png", System.Drawing.Imaging.ImageFormat.Png); } foreach (var sound in swf.FindTags <DefineSound>()) { using (var writer = new FileStream(sound.CharacterID + sound.GetFileExtension(), FileMode.Create, FileAccess.Write, FileShare.Write)) { var dat = sound.ExtractSound(); writer.Write(dat, 0, dat.Length); } } if (mapAnalysis) // kancolle mapdata analysis { var imagetags = swf.FindTags <ImageTag>(); Bitmap map = new Bitmap(768, 435); bool loaded = false; using (var g = Graphics.FromImage(map)) { foreach (var it in imagetags) { var img = it.ExtractImage(); if (img.Width == map.Width && img.Height == map.Height) { g.DrawImage(img, 0, 0); loaded = true; } img.Dispose(); } if (!loaded) { throw new InvalidOperationException("this data is not map"); } var placeobjects = swf.FindTags <PlaceObject2>(); for (int i = 0; ; i++) { string name = "line" + i; var linetag = placeobjects.FirstOrDefault(t => t.HasName && t.Name == name); if (linetag == null) { break; } var pos = new PointF(linetag.Matrix.TranslateX, linetag.Matrix.TranslateY); if (pos.X < 0) { pos.X = 0; } else if (pos.X >= map.Width) { pos.X = map.Width - 1; } if (pos.Y < 0) { pos.Y = 0; } else if (pos.Y >= map.Height) { pos.Y = map.Height - 1; } map.SetPixel((int)pos.X, (int)pos.Y, Color.Black); g.DrawString(i.ToString(), Font, Brushes.White, new PointF(pos.X + 1, pos.Y + 1)); g.DrawString(i.ToString(), Font, Brushes.Black, pos); var parentSprite = swf.FindTags <DefineSprite>().FirstOrDefault(t => t.CharacterID == linetag.CharacterID); if (parentSprite != null) { var innerplace = parentSprite.FindTags <PlaceObject2>().FirstOrDefault(); if (innerplace != null) { var shape = swf.FindTags <DefineShape>().FirstOrDefault(t => t.CharacterID == innerplace.CharacterID); if (shape != null) { var rect = shape.Bounds.ToPositiveRectangle(); g.DrawRectangle(Pens.Orange, linetag.Matrix.TranslateX + rect.X, linetag.Matrix.TranslateY + rect.Y, rect.Width, rect.Height); } } } } } if (pictureBox1.Image != null) { var img = pictureBox1.Image; pictureBox1.Image = null; img.Dispose(); } pictureBox1.Image = map; } } catch (Exception ex) { MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace, ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error); } }