/* 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); }