Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            string dir;

            if (args.Length == 1)
            {
                dir = Path.Combine(Path.GetDirectoryName(args[0]), Path.GetFileNameWithoutExtension(args[0]));
            }
            else if (args.Length != 2)
            {
                Console.WriteLine("Usage: u8extractor /path/to/file.arc [/extract/path]");
                return;
            }
            else
            {
                dir = args[1];
            }

            Stream filestream = new FileStream(args[0], FileMode.Open, FileAccess.Read, FileShare.Read);
            Stream stream     = filestream;

            try {
                DlcBin dlc = new DlcBin(filestream);
                stream = dlc.Data;
            } catch (FormatException) { }

            U8 u8 = new U8(stream);

            u8.Root.Extract(dir);

            filestream.Close();
        }
Ejemplo n.º 2
0
 static void PlatformDetection_DetectWiiDlcBin(string path, DlcBin dlc, PlatformList platforms)
 {
     if (DetectDirectoryNode != null)
     {
         try {
             U8 u8 = new U8(dlc.Data);
             DetectDirectoryNode(path, u8.Root, platforms);
         } catch (FormatException) { } catch (Exception exception) {
             Exceptions.Warning(exception, "Trying to open as DLC U8: " + path);
         }
     }
 }
Ejemplo n.º 3
0
        private void AddSongFromBins(PlatformData data, SongData song, string dtapath, string contentpath, ProgressIndicator progress, bool replace = false)
        {
            if (File.Exists(contentpath) && File.Exists(dtapath))
            {
                Stream contentfile = null;
                Stream dtafile     = null;
                if (IterateBins)
                {
                    contentfile = new DelayedStream(data.Cache.GenerateFileStream(contentpath, FileMode.Open));
                    DlcBin content = new DlcBin(contentfile);
                    U8     u8      = new U8(content.Data);

                    // Read album art from the preview bin
                    dtafile = new DelayedStream(data.Cache.GenerateFileStream(dtapath, FileMode.Open));
                    DlcBin        dtabin  = new DlcBin(dtafile);
                    U8            dtau8   = new U8(dtabin.Data);
                    string        genpath = "/content/songs/" + song.ID + "/gen";
                    DirectoryNode dtagen  = dtau8.Root.Navigate(genpath) as DirectoryNode;
                    if (dtagen != null)
                    {
                        DirectoryNode contentgen = u8.Root.Navigate(genpath) as DirectoryNode;
                        if (contentgen != null)
                        {
                            contentgen.AddChildren(dtagen.Files);
                        }
                    }

                    data.Session["songdir"] = u8.Root;
                }

                if (replace)
                {
                    foreach (FormatData formatdata in data.Songs)
                    {
                        if (formatdata.Song.ID == song.ID)
                        {
                            base.DeleteSong(data, formatdata, progress);
                            break;
                        }
                    }
                }

                AddSong(data, song, progress);                 // TODO: Add dta bin to songdir for album art

                if (IterateBins)
                {
                    data.Session.Remove("songdir");
                    contentfile.Close();
                    dtafile.Close();
                }
            }
        }
Ejemplo n.º 4
0
        static void PlatformDetection_DetectDirectoryNode(string path, DirectoryNode root, List <Pair <Engine, Game> > platforms)
        {
            FileNode file = root.Navigate("001.bin") as FileNode;

            if (file == null)
            {
                return;
            }
            try {
                DlcBin bin = new DlcBin(file.Data);
                if (bin.Bk.TitleID == 0x0001000053584145)
                {
                    platforms.Add(new Pair <Engine, Game>(Instance, Game.GuitarHeroWorldTour));
                }
            } catch { }
            file.Data.Close();
        }
Ejemplo n.º 5
0
        public override bool AddSong(PlatformData data, SongData song, ProgressIndicator progress)
        {
            int index = int.Parse(song.ID.Substring(3));
            //song.ID = "dlc" + ImportMap.GetShortName(song.Name);

            FormatData formatdata = new TemporaryFormatData(song, data);

            NeversoftMetadata.SaveSongItem(formatdata);

            DirectoryNode dir = data.Session["rootdir"] as DirectoryNode;

            FileNode binfile = dir.Navigate(Util.Pad(index.ToString(), 3) + ".bin") as FileNode;

            if (binfile == null)
            {
                return(false);
            }
            DlcBin bin = new DlcBin(binfile.Data);
            U8     u8  = new U8(bin.Data);

            FileNode chartpak = u8.Root.Find(song.ID + "_song.pak.ngc", SearchOption.AllDirectories) as FileNode;
            FileNode textpak  = u8.Root.Find(song.ID + "_text.pak.ngc", SearchOption.AllDirectories) as FileNode;

            FileNode audiofile = u8.Root.Find(song.ID + ".bik", SearchOption.AllDirectories) as FileNode;

            if (chartpak == null || textpak == null || audiofile == null)
            {
                return(false);
            }

            ChartFormatGH4.Instance.Create(formatdata, new Stream[] { chartpak.Data, textpak.Data }, PlatformGH5WiiDisc.ImportExpertPlus);

            if (audiofile != null)
            {
                AudioFormatBink.Instance.Create(formatdata, audiofile.Data, null, null);
            }

            data.AddSong(formatdata);

            chartpak.Data.Close();

            return(true);
        }
Ejemplo n.º 6
0
		public override PlatformData Create(string path, Game game, ProgressIndicator progress)
		{
			PlatformData data = new PlatformData(this, game);

			DirectoryNode maindir = DirectoryNode.FromPath(path, data.Cache, FileAccess.Read);

			char[] regions = new char[] { 'E', 'P' };

			DirectoryNode dir = maindir.Navigate("private/wii/data", false, true) as DirectoryNode;
			if (dir == null)
				dir = maindir;

			for (char letter = 'A'; letter <= 'Z'; letter++) {
				foreach (char region in regions) {
					DirectoryNode subdir = dir.Find("SZ" + letter + region, true) as DirectoryNode;
					if (subdir == null)
						continue;

					foreach (FileNode file in subdir.Files) {
						if (String.Compare(Path.GetExtension(file.Name), ".bin", true) != 0)
							continue;

						try {
							file.Data.Position = 0;
							DlcBin bin = new DlcBin(file.Data);
							U8 u8;
							try {
								u8 = new U8(bin.Data);
							} catch (FormatException) {
								file.Data.Close();
								continue;
							}
							FileNode songsdta = u8.Root.Find("songs.dta", SearchOption.AllDirectories) as FileNode;
							if (songsdta == null) {
								file.Data.Close();
								continue;
							}

							DTB.NodeTree dtb = DTA.Create(songsdta.Data);
							SongsDTA dta = SongsDTA.Create(dtb);
							file.Data.Close();
							
							SongData song = HarmonixMetadata.GetSongData(data, dtb);

							string contentbin = dta.Song.Name.Substring(9, 3); // Example, "dlc/sZAE/023/content/songs/simpleman/simpleman"

							FileNode contentfile = subdir.Find(contentbin + ".bin", true) as FileNode;
							if (contentfile == null)
								continue;

							FormatData formatdata = new TemporaryFormatData(song, data);

							Create(formatdata, file.Data, contentfile.Data);
							
							data.AddSong(formatdata);

							contentfile.Data.Close();
						} catch (FormatException) { } // Not a DLC bin we care about
					}
				}
			}

			return data;
		}
Ejemplo n.º 7
0
        static void PlatformDetection_DetectFile(string path, Stream stream, PlatformList platforms)
        {
            if (DetectWiiDisc != null)
            {
                try {
                    stream.Position = 0;
                    Disc disc = new Disc(stream);
                    DetectWiiDisc(path, disc, platforms);
                } catch (FormatException) { } catch (Exception exception) {
                    Exceptions.Warning(exception, "Trying to open as Wiidisc: " + path);
                }
            }

            if (DetectIso9660 != null)
            {
                try {
                    stream.Position = 0;
                    Iso9660 disc = new Iso9660(stream);
                    DetectIso9660(path, disc, platforms);
                } catch (FormatException) { } catch (Exception exception) {
                    Exceptions.Warning(exception, "Trying to open as ISO: " + path);
                }
            }

            if (DetectXbox360Dlc != null)
            {
                try {
                    stream.Position = 0;
                    StfsArchive stfs = new StfsArchive(stream);
                    DetectXbox360Dlc(path, stfs, platforms);
                } catch (FormatException) { } catch (Exception exception) {
                    Exceptions.Warning(exception, "Trying to open as 360 DLC: " + path);
                }
            }

            if (DetectWiiU8 != null)
            {
                try {
                    stream.Position = 0;
                    U8 u8 = new U8(stream);
                    DetectWiiU8(path, u8, platforms);
                } catch (FormatException) { } catch (Exception exception) {
                    Exceptions.Warning(exception, "Trying to open as U8: " + path);
                }
            }

            if (DetectWiiDlcBin != null)
            {
                try {
                    stream.Position = 0;
                    DlcBin dlc = new DlcBin(stream);
                    DetectWiiDlcBin(path, dlc, platforms);
                } catch (FormatException) { } catch (Exception exception) {
                    Exceptions.Warning(exception, "Trying to open as Wii DLC: " + path);
                }
            }

            if (DetectHarmonixArk != null)
            {
                string extension = Path.GetExtension(path).ToLower();
                if (extension.EndsWith(".ark") || extension.EndsWith(".hdr"))
                {
                    PlatformDetection_DetectDirectory(Path.GetDirectoryName(path), platforms);
                }
            }
        }
Ejemplo n.º 8
0
        public override PlatformData Create(string path, Game game, ProgressIndicator progress)
        {
            PlatformData data = new PlatformData(this, game);

            DirectoryNode dir = data.GetDirectoryStructure(path);

            FileNode binfile = dir.Navigate("001.bin") as FileNode;

            if (binfile == null)
            {
                Exceptions.Error("Unable to open Guitar Hero World Tour DLC because 001.bin is missing.");
            }

            data.Session["rootdir"] = dir;

            try {
                DlcBin   bin          = new DlcBin(binfile.Data);
                U8       u8           = new U8(bin.Data);
                FileNode listfile     = u8.Root.Navigate("DLC1.pak.ngc") as FileNode;
                Pak      qb           = new Pak(new EndianReader(listfile.Data, Endianness.BigEndian));
                FileNode songlistfile = qb.Root.Find("catalog_info.qb.ngc", SearchOption.AllDirectories) as FileNode;
                QbFile   songlist     = new QbFile(songlistfile.Data, PakFormat);

                StringList strings = new StringList();
                foreach (Pak.Node node in qb.Nodes)
                {
                    if (!node.Filename.HasValue())
                    {
                        strings.ParseFromStream(node.Data);
                    }
                }

                List <QbKey> listkeys = new List <QbKey>();
                foreach (uint songlistkey in NeversoftMetadata.SonglistKeys)
                {
                    QbKey        key  = QbKey.Create(songlistkey);
                    QbItemStruct list = songlist.FindItem(key, true) as QbItemStruct;
                    if (list != null && list.Items.Count > 0)
                    {
                        listkeys.Add(key);
                    }
                }

                Stream       str    = new FileStream(@"C:\ghwt.xml", FileMode.Create);
                StreamWriter writer = new StreamWriter(str);

                progress.NewTask(listkeys.Count);
                foreach (QbKey songlistkey in listkeys)
                {
                    QbItemStruct list = songlist.FindItem(songlistkey, true) as QbItemStruct;

                    progress.NewTask(list.Items.Count);

                    foreach (QbItemArray item in list.Items.OfType <QbItemArray>())
                    {
                        item.Items[0].ItemQbKey = item.ItemQbKey;
                        SongData song = NeversoftMetadata.GetSongData(data, item.Items[0] as QbItemStruct, strings);

                        writer.WriteLine("\t<song id=\"" + song.ID + "\">");
                        writer.WriteLine("\t\t<pack>Guitar Hero World Tour DLC</pack>");
                        writer.WriteLine("\t\t<nameprefix>[GHWT DLC]</nameprefix>");
                        writer.WriteLine("\t\t<name>" + song.Name + "</name>");
                        writer.WriteLine("\t\t<artist>" + song.Artist + "</artist>");
                        writer.WriteLine("\t\t<album>" + song.Album + "</album>");
                        writer.WriteLine("\t\t<genre>" + song.Genre + "</genre>");
                        writer.WriteLine("\t\t<track>" + song.AlbumTrack.ToString() + "</track>");
                        writer.WriteLine("\t\t<difficulty instrument=\"band\" rank=\"1\" />");
                        writer.WriteLine("\t\t<difficulty instrument=\"guitar\" rank=\"1\" />");
                        writer.WriteLine("\t\t<difficulty instrument=\"bass\" rank=\"1\" />");
                        writer.WriteLine("\t\t<difficulty instrument=\"drum\" rank=\"1\" />");
                        writer.WriteLine("\t\t<difficulty instrument=\"vocals\" rank=\"1\" />");
                        writer.WriteLine("\t</song>");

                        try {
                            AddSong(data, song, progress);
                        } catch (Exception exception) {
                            Exceptions.Warning(exception, "Unable to properly parse " + song.Name);
                        }
                        progress.Progress();
                    }

                    progress.EndTask();
                    progress.Progress();
                }
                progress.EndTask();
                writer.Close();

                binfile.Data.Close();
            } catch (Exception exception) {
                Exceptions.Error(exception, "An error occurred while parsing the Guitar Hero World Tour DLC list.");
            }

            return(data);
        }
Ejemplo n.º 9
0
        static void Main(string[] args)
        {
            string dir = string.Empty;

            if (args.Length == 2)
            {
                dir = args[1];
            }
            else if (args.Length == 1)
            {
                dir = args[0] + ".ext";
            }
            else
            {
                Console.WriteLine("Usage: wiidiscextractor /path/to/disc.iso /extract/path");
                return;
            }

            Directory.CreateDirectory(dir);

            try {
                if (!Directory.Exists(args[0]))
                {
                    throw new FormatException();
                }
                DelayedStreamCache cache = new DelayedStreamCache();
                DirectoryNode      dirn  = DirectoryNode.FromPath(args[0], cache, FileAccess.Read, FileShare.Read);
                DirectoryNode      gen   = dirn.Navigate("gen", false, true) as DirectoryNode;
                if (gen == null)                 // Just in case we're given the "wrong" directory that directly contains the ark
                {
                    gen = dirn;
                }

                List <Pair <int, Stream> > arkfiles = new List <Pair <int, Stream> >();
                Stream hdrfile = null;
                foreach (FileNode file in gen.Files)
                {
                    if (file.Name.ToLower().EndsWith(".hdr"))
                    {
                        hdrfile = file.Data;
                    }
                    else if (file.Name.ToLower().EndsWith(".ark"))
                    {
                        Match match = Regex.Match(file.Name.ToLower(), @"_(\d+).ark");
                        if (match.Success)
                        {
                            arkfiles.Add(new Pair <int, Stream>(int.Parse(match.Groups[1].Value), file.Data));
                        }
                        else
                        {
                            arkfiles.Add(new Pair <int, Stream>(0, file.Data));
                        }
                    }
                }

                // FreQuency/Amplitude where the header is the ark
                if (hdrfile == null)
                {
                    if (arkfiles.Count == 1)
                    {
                        hdrfile = arkfiles[0].Value;
                        arkfiles.Clear();
                    }
                    else
                    {
                        throw new FormatException();
                    }
                }

                Ark ark = new Ark(new EndianReader(hdrfile, Endianness.LittleEndian), arkfiles.OrderBy(f => f.Key).Select(f => f.Value).ToArray());
                ark.Root.Extract(dir);
                cache.Dispose();
            } catch (FormatException) {
                Stream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
                try {
                    Iso9660 iso = new Iso9660(stream);
                    iso.Root.Extract(dir);
                } catch (Exception) {
                    try {
                        stream.Position = 0;
                        Disc disc = new Disc(stream);

                        File.WriteAllText(Path.Combine(dir, "title"), disc.Title);

                        foreach (var partition in disc.Partitions)
                        {
                            string path = Path.Combine(dir, "partition" + disc.Partitions.IndexOf(partition).ToString());
                            Directory.CreateDirectory(path);

                            partition.Root.Root.Extract(Path.Combine(path, "data"));

                            FileStream file = new FileStream(Path.Combine(path, "partition.tik"), FileMode.Create, FileAccess.Write);
                            partition.Ticket.Save(file);
                            file.Close();

                            file = new FileStream(Path.Combine(path, "partition.tmd"), FileMode.Create, FileAccess.Write);
                            partition.TMD.Save(file);
                            file.Close();

                            file = new FileStream(Path.Combine(path, "partition.certs"), FileMode.Create, FileAccess.Write);
                            file.Write(partition.CertificateChain);
                            file.Close();
                        }
                    } catch {
                        try {
                            stream.Position = 0;
                            DlcBin bin = new DlcBin(stream);
                            U8     u8  = new U8(bin.Data);
                            u8.Root.Extract(dir);
                        } catch {
                            try {
                                stream.Position = 0;
                                U8 u8 = new U8(stream);
                                u8.Root.Extract(dir);
                            } catch {
                                stream.Position = 0;
                                Rarc rarc = new Rarc(stream);
                                rarc.Root.Extract(dir);
                            }
                        }
                    }
                }
                stream.Close();
            }
        }
Ejemplo n.º 10
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();
        }