Пример #1
0
        public override void SaveSong(PlatformData data, FormatData formatdata, ProgressIndicator progress)
        {
            string path = data.Session["maindirpath"] as string;

            string otitle;
            ushort oindex;

            progress.NewTask(10);

            using (DelayedStreamCache cache = new DelayedStreamCache()) {
                progress.SetNextWeight(6);
                string          audioextension = ".mogg";
                Stream          audio          = null;
                Stream          preview        = null;
                AudioFormat     audioformat    = null;
                IList <IFormat> formats        = formatdata.Formats;
                if (formats.Contains(AudioFormatRB2Mogg.Instance))
                {
                    audio       = AudioFormatRB2Mogg.Instance.GetAudioStream(formatdata);
                    preview     = AudioFormatRB2Mogg.Instance.GetPreviewStream(formatdata);
                    audioformat = AudioFormatRB2Mogg.Instance.DecodeAudioFormat(formatdata);
                }
                else if (formats.Contains(AudioFormatRB2Bink.Instance))
                {
                    audio   = AudioFormatRB2Bink.Instance.GetAudioStream(formatdata);
                    preview = AudioFormatRB2Bink.Instance.GetPreviewStream(formatdata, progress);
                    if (!formatdata.HasStream(preview))
                    {
                        cache.AddStream(preview);
                    }
                    audioformat    = AudioFormatRB2Bink.Instance.DecodeAudioFormat(formatdata);
                    audioextension = ".bik";
                }
                else
                {
                    throw new NotSupportedException();
                }

                progress.Progress(6);

                ChartFormat chartformat = (formatdata.GetFormat(FormatType.Chart) as IChartFormat).DecodeChart(formatdata, progress);

                Stream album   = null;
                Stream chart   = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.ChartFile);
                Stream pan     = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.PanFile);
                Stream weights = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.WeightsFile);
                Stream milo    = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.MiloFile);

                progress.SetNextWeight(2);

                if (chart != null && ChartFormatRB.Instance.NeedsFixing(formatdata))
                {
                    formatdata.CloseStream(chart);
                    chart = null;
                }

                if (chart == null)
                {
                    chart = new TemporaryStream();
                    cache.AddStream(chart);
                    AdjustChart(formatdata.Song, audioformat, chartformat).ToMidi().ToMid().Save(chart);
                    chart.Position = 0;
                }

                if (weights == null)
                {
                    weights = new TemporaryStream();
                    cache.AddStream(weights);
                    CreateWeights(weights, chartformat);
                    weights.Position = 0;
                }

                if (pan == null)
                {
                    pan = new TemporaryStream();
                    cache.AddStream(pan);
                    CreatePan(pan, chartformat);
                    pan.Position = 0;
                }

                if (milo == null)
                {
                    milo = formatdata.GetStream(ChartFormatRB.Instance, ChartFormatRB.Milo3File);
                    if (milo == null)
                    {
                        milo = new MemoryStream(Properties.Resources.rawksd_milo);
                    }
                    else
                    {
                        Stream milostream = new TemporaryStream();
                        cache.AddStream(milostream);
                        Milo   milofile = new Milo(new EndianReader(milo, Endianness.LittleEndian));
                        FaceFX fx       = new FaceFX(new EndianReader(milofile.Data[0], Endianness.BigEndian));

                        TemporaryStream fxstream = new TemporaryStream();
                        fx.Save(new EndianReader(fxstream, Endianness.LittleEndian));
                        milofile.Data[0]    = fxstream;
                        milofile.Compressed = true;
                        milofile.Save(new EndianReader(milostream, Endianness.LittleEndian));
                        fxstream.Close();
                        formatdata.CloseStream(milo);
                        milo          = milostream;
                        milo.Position = 0;
                    }
                }

                //if (album == null)
                //	album = new MemoryStream(Properties.Resources.rawksd_albumart);

                progress.Progress(2);

                SongData song = new SongData(formatdata.Song);

                SongsDTA dta = GetSongsDTA(song, audioformat);

                if (album == null)
                {
                    dta.AlbumArt = false;
                }
                else
                {
                    dta.AlbumArt = true;
                }

                dta.Song.MidiFile = "dlc/content/songs/" + song.ID + "/" + song.ID + ".mid";

                DTB.NodeTree dtb = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song));

                MemoryStream songsdta = new MemoryStream();
                cache.AddStream(songsdta);
                dtb.SaveDTA(songsdta);
                songsdta.Position = 0;

                U8            appdta = new U8();
                DirectoryNode dir    = new DirectoryNode("content");
                appdta.Root.AddChild(dir);
                DirectoryNode songsdir = new DirectoryNode("songs");
                dir.AddChild(songsdir);
                DirectoryNode songdir = new DirectoryNode(song.ID);
                songsdir.AddChild(songdir);
                songdir.AddChild(new FileNode(song.ID + "_prev.mogg", preview));
                songdir.AddChild(new FileNode("songs.dta", songsdta));
                DirectoryNode gendir;
                if (dta.AlbumArt.Value && album != null)
                {
                    gendir = new DirectoryNode("gen");
                    songdir.AddChild(gendir);
                    gendir.AddChild(new FileNode(song.ID + "_nomip_keep.bmp_wii", album));
                }

                U8 appsong = new U8();
                dir = new DirectoryNode("content");
                appsong.Root.AddChild(dir);
                songsdir = new DirectoryNode("songs");
                dir.AddChild(songsdir);
                songdir = new DirectoryNode(song.ID);
                songsdir.AddChild(songdir);
                songdir.AddChild(new FileNode(song.ID + audioextension, audio));
                songdir.AddChild(new FileNode(song.ID + ".mid", chart));
                songdir.AddChild(new FileNode(song.ID + ".pan", pan));
                gendir = new DirectoryNode("gen");
                songdir.AddChild(gendir);
                gendir.AddChild(new FileNode(song.ID + ".milo_wii", milo));
                gendir.AddChild(new FileNode(song.ID + "_weights.bin", weights));

                Stream memoryDta = new TemporaryStream();
                cache.AddStream(memoryDta);
                appdta.Save(memoryDta);

                Stream memorySong = new TemporaryStream();
                cache.AddStream(memorySong);
                appsong.Save(memorySong);

                formatdata.CloseStream(audio);
                formatdata.CloseStream(preview);
                formatdata.CloseStream(chart);
                formatdata.CloseStream(album);
                formatdata.CloseStream(pan);
                formatdata.CloseStream(weights);
                formatdata.CloseStream(milo);

                FindUnusedContent(data, formatdata.Song, out otitle, out oindex);
                TMD tmd = GenerateDummyTMD(otitle);

                dta.Song.Name = "dlc/" + otitle + "/" + Util.Pad(oindex.ToString(), 3) + "/content/songs/" + song.ID + "/" + song.ID;
                dtb           = dta.ToDTB(PlatformRawkFile.Instance.IsRawkSD2(song));
                HarmonixMetadata.SetSongsDTA(song, dtb);

                string dirpath = Path.Combine(Path.Combine(path, "rawk"), "rb2");
                if (!Directory.Exists(Path.Combine(dirpath, "customs")))
                {
                    Directory.CreateDirectory(Path.Combine(dirpath, "customs"));
                }
                Directory.CreateDirectory(Path.Combine(Path.Combine(dirpath, "customs"), song.ID));
                FileStream savestream = new FileStream(Path.Combine(Path.Combine(Path.Combine(dirpath, "customs"), song.ID), "data"), FileMode.Create);
                dtb.Save(new EndianReader(savestream, Endianness.LittleEndian));
                savestream.Close();

                TmdContent contentDta = new TmdContent();
                contentDta.ContentID = oindex;
                contentDta.Index     = oindex;
                contentDta.Type      = 0x4001;

                TmdContent contentSong = new TmdContent();
                contentSong.ContentID = oindex + 1U;
                contentSong.Index     = (ushort)(oindex + 1);
                contentSong.Type      = 0x4001;

                memoryDta.Position = 0;
                contentDta.Hash    = Util.SHA1Hash(memoryDta);
                contentDta.Size    = memoryDta.Length;

                memorySong.Position = 0;
                contentSong.Hash    = Util.SHA1Hash(memorySong);
                contentSong.Size    = memorySong.Length;

                for (int i = 1; i <= oindex + 1; i++)
                {
                    if (i == oindex)
                    {
                        tmd.Contents.Add(contentDta);
                    }
                    else if (i == oindex + 1)
                    {
                        tmd.Contents.Add(contentSong);
                    }
                    else
                    {
                        tmd.Contents.Add(new TmdContent()
                        {
                            Index = (ushort)i, ContentID = (uint)i, Size = 1, Type = 0x4001
                        });
                    }
                }

                tmd.Fakesign();

                uint consoleid = GetConsoleID(path);

                progress.Progress();

                dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), "sZAE");
                TemporaryStream binstream;
                DlcBin          bin;
                if (consoleid != 0 && !File.Exists(Path.Combine(dirpath, "000.bin")))
                {
                    Directory.CreateDirectory(dirpath);
                    binstream = new TemporaryStream();
                    binstream.Write(Properties.Resources.rawksd_000bin, 0, Properties.Resources.rawksd_000bin.Length);
                    binstream.Position = 8;
                    new EndianReader(binstream, Endianness.BigEndian).Write(consoleid);
                    binstream.ClosePersist();
                    File.Move(binstream.Name, Path.Combine(dirpath, "000.bin"));
                    binstream.Close();
                }

                dirpath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(path, "private"), "wii"), "data"), otitle);
                if (!Directory.Exists(dirpath))
                {
                    Directory.CreateDirectory(dirpath);
                }

                binstream        = new TemporaryStream();
                bin              = new DlcBin();
                bin.Bk.ConsoleID = consoleid;
                bin.TMD          = tmd;
                bin.Content      = tmd.Contents[oindex];
                bin.Data         = memoryDta;
                bin.Generate();
                bin.Bk.ContentSize = bin.Bk.TotalSize = 0;
                bin.Bk.TitleID     = 0x00010000535A4145UL;
                bin.Save(binstream);
                binstream.ClosePersist();
                string dtabinpath = Path.Combine(dirpath, Util.Pad(oindex.ToString(), 3) + ".bin");
                Util.Delete(dtabinpath);
                File.Move(binstream.Name, dtabinpath);
                binstream.Close();

                binstream        = new TemporaryStream();
                bin              = new DlcBin();
                bin.Bk.ConsoleID = consoleid;
                bin.TMD          = tmd;
                bin.Content      = tmd.Contents[oindex + 1];
                bin.Data         = memorySong;
                bin.Generate();
                bin.Bk.ContentSize = bin.Bk.TotalSize = 0;
                bin.Bk.TitleID     = 0x00010000535A4145UL;
                bin.Save(binstream);
                binstream.ClosePersist();
                string songbinpath = Path.Combine(dirpath, Util.Pad((oindex + 1).ToString(), 3) + ".bin");
                Util.Delete(songbinpath);
                File.Move(binstream.Name, songbinpath);
                binstream.Close();

                data.Mutex.WaitOne();
                string mainbinpath = Path.Combine(dirpath, "000.bin");
                if (!File.Exists(mainbinpath))
                {
                    binstream        = new TemporaryStream();
                    bin              = new DlcBin();
                    bin.Bk.ConsoleID = consoleid;
                    bin.TMD          = tmd;
                    bin.Content      = tmd.Contents[0];
                    bin.Data         = new MemoryStream(Properties.Resources.rawksd_savebanner, false);
                    bin.Generate();
                    bin.Bk.TitleID = 0x00010000535A4145UL;
                    bin.Save(binstream);
                    binstream.ClosePersist();
                    File.Move(binstream.Name, mainbinpath);
                    binstream.Close();
                }

                AddSongFromBins(data, song, dtabinpath, songbinpath, progress, true);

                SaveDTBCache(data);

                data.Mutex.ReleaseMutex();

                cache.Dispose();

                progress.Progress();
            }

            progress.EndTask();
        }