Esempio n. 1
0
        private static async Task PatchMainDolAsync(List <MapDescriptor> mapDescriptors, DataFileSet cacheFileSet, DataFileSet riivFileSet, IProgress <ProgressInfo> progress, CancellationToken ct)
        {
            Directory.CreateDirectory(Path.GetDirectoryName(riivFileSet.main_dol));
            File.Copy(cacheFileSet.main_dol, riivFileSet.main_dol, true);

            // expand dol if not already expanded
            // ehmm.. actually lets not do this -> range 0x80001800 till 0x80003000 is already used by gecko codes
            //if (mainDol.toFileAddress(0x80001800) == -1)
            //{
            //    await ExeWrapper.createNewTextSection(riivFileSet.main_dol, 0x80001800, 0x1800, ct, progress);
            //    mainDol.setSections(await ExeWrapper.readSections(riivFileSet.main_dol, ct, progress));
            //}

            progress?.Report("Detect the sections in main.dol file...");
            List <AddressSection> sections = await ExeWrapper.readSections(riivFileSet.main_dol, ct, ProgressInfo.makeNoProgress(progress)).ConfigureAwait(false);

            MainDol mainDol;

            using (var stream = File.OpenRead(riivFileSet.main_dol))
            {
                EndianBinaryReader binReader = new EndianBinaryReader(EndianBitConverter.Big, stream);
                mainDol = new MainDol(binReader, sections, progress);
            }

            using (Stream baseStream = File.Open(riivFileSet.main_dol, FileMode.Open))
            {
                try
                {
                    EndianBinaryWriter stream = new EndianBinaryWriter(EndianBitConverter.Big, baseStream);
                    mainDol.writeMainDol(stream, mapDescriptors, progress);
                }
                finally
                {
                    progress.Report("Before Patch:");
                    progress.Report("Amount of free space available in main.dol: " + mainDol.freeSpaceManager.calculateTotalFreeSpace() + " bytes");
                    progress.Report("Amount of free space in the largest block in main.dol: " + mainDol.freeSpaceManager.calculateLargestFreeSpaceBlockSize() + " bytes");
                    progress.Report("After Patch:");
                    progress.Report("Amount of free space available in main.dol: " + mainDol.freeSpaceManager.calculateTotalRemainingFreeSpace() + " bytes");
                    progress.Report("Amount of free space in the largest block in main.dol: " + mainDol.freeSpaceManager.calculateLargestRemainingFreeSpaceBlockSize() + " bytes");
                    int bytesWritten = mainDol.freeSpaceManager.calculateTotalFreeSpace() - mainDol.freeSpaceManager.calculateTotalRemainingFreeSpace();
                    progress.Report("Total free space used: " + bytesWritten + " bytes");
                }
            }
        }
        public static async Task <List <MapDescriptor> > Open(string input, IProgress <ProgressInfo> progress, CancellationToken ct, string cachePath = null)
        {
            progress?.Report(0);

            if (string.IsNullOrWhiteSpace(input) || input.ToLower() == "none")
            {
                throw new ArgumentNullException("Can't load wbfs or iso file as the input file name is not set.");
            }

            input = DoPathCorrections(input, false);
            var cacheFileSet = new DataFileSet(GetCachePath(input, cachePath));

            if (IsImageFileExtension(input))
            {
                progress?.Report("Extract iso/wbfs...");
                await ExeWrapper.extractFullIsoAsync(input, cacheFileSet.rootDir, ct, ProgressInfo.makeSubProgress(progress, 0, 90)).ConfigureAwait(false);
            }

            progress?.Report("Detect the sections in main.dol file...");
            List <AddressSection> sections = await ExeWrapper.readSections(cacheFileSet.main_dol, ct, ProgressInfo.makeSubProgress(progress, 90, 95)).ConfigureAwait(false);

            progress?.Report("Read data from main.dol file...");

            List <MapDescriptor> mapDescriptors;

            using (var stream = File.OpenRead(cacheFileSet.main_dol))
            {
                EndianBinaryReader binReader = new EndianBinaryReader(EndianBitConverter.Big, stream);
                var mainDol = new MainDol(binReader, sections, progress);
                mapDescriptors = mainDol.readMainDol(binReader, progress);

                progress?.Report(97);
                progress?.Report("Read localization files...");
                LoadUIMessages(mapDescriptors, cacheFileSet, ProgressInfo.makeSubProgress(progress, 20, 60), ct);
            }

            progress?.Report(100);
            progress?.Report("Loaded successfully.");
            CleanTemp();
            CleanRiivolution();

            return(mapDescriptors);
        }