Example #1
0
        /* TODO: use proper arguments parser */

        static int ListFiles(ReadOnlySpan <string> args)
        {
            if (args.Length != 1)
            {
                Console.Error.WriteLine("Usage: ShinDataUtil rom-list [filename]");
                return(1);
            }
            var filename = args[0];

            using var archive = new FileReadableGameArchive(filename);
            int count = 0;

            foreach (var file in archive.EnumerateAllFiles())
            {
                count++;
                NonBlockingConsole.WriteLine("{0,10} {1,10} {2}", file.DataOffset, file.Size, file.Path);
            }
            NonBlockingConsole.WriteLine($"In total: {count} files");

            return(0);
        }
        /// <summary>
        /// Quickly replace a certain file in rom
        /// Does some hacks, leaves old file contents, so it should not be used repeatedly
        /// </summary>
        public static void ReplaceFile(string inromPath, Stream outrom, Stream injfile, string targetName)
        {
            using var inrom       = File.OpenRead(inromPath);
            using var readableRom = new FileReadableGameArchive(inromPath);

            var header = new RomHeader();

            inrom.Read(SpanUtil.AsBytes(ref header));

            outrom.Seek(0, SeekOrigin.Begin);
            inrom.Seek(0, SeekOrigin.Begin);
            inrom.CopyTo(outrom);

            var fileEntry         = readableRom.FindFile(targetName);
            var rawEntry          = new RomEntry();
            var rawEntryOffset    = Marshal.SizeOf <RomHeader>() + fileEntry.SourceOffset;
            var rawEntryBytesSpan = SpanUtil.AsBytes(ref rawEntry);

            outrom.Seek(rawEntryOffset, SeekOrigin.Begin);
            outrom.Read(rawEntryBytesSpan);
            outrom.Seek(rawEntryOffset, SeekOrigin.Begin);

            var newDataOffset = outrom.Length;

            while (newDataOffset % header.offsetMultiplier != 0)
            {
                newDataOffset++;
            }

            rawEntry.RawDataOffset = newDataOffset / header.offsetMultiplier;
            rawEntry.DataSize      = (int)injfile.Length;

            outrom.Write(rawEntryBytesSpan);

            outrom.Seek(newDataOffset, SeekOrigin.Begin);

            injfile.CopyTo(outrom);
        }