public void AddTextureIfNotExists(uint key, DuplicatableStream texture) { SkitTex containedTexture; if (Cache.TryGetValue(key, out containedTexture)) { const bool verify = false; if (verify) { using (DuplicatableStream otex = containedTexture.Stream.Duplicate()) using (DuplicatableStream ntex = texture.Duplicate()) { otex.Position = 0; ntex.Position = 0; if (!(otex.Length == ntex.Length && StreamUtils.IsIdentical(otex, ntex, otex.Length))) { throw new Exception("texture added does not match known texture"); } } } } else { Cache.Add(key, new SkitTex() { Stream = texture.Duplicate() }); } }
public FPS4(DuplicatableStream headerStream, DuplicatableStream contentStream = null) { if (!LoadFile(headerStream, contentStream != null ? contentStream : headerStream)) { throw new Exception("Failed loading FPS4."); } }
public SE3(DuplicatableStream stream, EndianUtils.Endianness?endian, TextUtils.GameTextEncoding encoding) { if (!LoadFile(stream, endian, encoding)) { throw new Exception("Loading SE3 failed!"); } }
public FPS4(DuplicatableStream headerStream, DuplicatableStream contentStream = null, bool printProgressToConsole = false) { if (!LoadFile(headerStream, contentStream != null ? contentStream : headerStream, printProgressToConsole)) { throw new Exception("Failed loading FPS4."); } }
public PackFileInfo(PackFileInfo other) { Name = other.Name; Length = other.Length; RelativePath = other.RelativePath; DataStream = other.DataStream != null ? other.DataStream.Duplicate() : null; DuplicateOf = other.DuplicateOf; }
public PartialStream(DuplicatableStream stream, long position, long length) { if (position < 0) { throw new Exception("Invalid position, must be positive."); } if (length < 0) { throw new Exception("Invalid length, must be positive."); } if (stream is PartialStream) { // optimization to better chain partial stream of partial stream PartialStream parent = stream as PartialStream; BaseStreamInternal = parent.BaseStreamInternal.Duplicate(); Initialized = false; PartialStart = parent.PartialStart + position; PartialLength = length; CurrentPosition = 0; } else { BaseStreamInternal = stream.Duplicate(); Initialized = false; PartialStart = position; PartialLength = length; CurrentPosition = 0; } }
public EndianUtils.Endianness Endian; // not actually a field in the header, at least not here -- might be the first byte? public NubHeader(DuplicatableStream stream, EndianUtils.Endianness?endian) { Magic = stream.ReadUInt64(EndianUtils.Endianness.LittleEndian); EndianUtils.Endianness suspectedEndian; if (Magic == 0x10200) { suspectedEndian = EndianUtils.Endianness.BigEndian; } else if (Magic == 0x10201) { suspectedEndian = EndianUtils.Endianness.LittleEndian; } else { throw new Exception("unexpected magic in NUB"); } EndianUtils.Endianness e = endian ?? suspectedEndian; Fileid = stream.ReadUInt32(e); // or something like that? seems unique per archive in each game EntryCount = stream.ReadUInt32(e); StartOfFiles = stream.ReadUInt32(e); FilesSize = stream.ReadUInt32(e); StartOfEntries = stream.ReadUInt32(e); StartOfHeaders = stream.ReadUInt32(e); Endian = e; }
public static void ExtractNub(DuplicatableStream duplicatableStream, string targetFolder, EndianUtils.Endianness?e) { Directory.CreateDirectory(targetFolder); using (var nub = new NUB(duplicatableStream, e)) { nub.Extract(targetFolder); } }
public TrophyTrp(HyoutaPluginBase.DuplicatableStream stream, EndianUtils.Endianness endian = EndianUtils.Endianness.BigEndian) { Stream = stream.Duplicate(); Endian = endian; try { Stream.ReStart(); Magic = Stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian); if (Magic != 0x004DA2DC) { throw new Exception("invalid magic"); } Unknown2 = Stream.ReadUInt32().FromEndian(endian); Unknown3 = Stream.ReadUInt32().FromEndian(endian); Filesize = Stream.ReadUInt32().FromEndian(endian); Filecount = Stream.ReadUInt32().FromEndian(endian); Unknown6 = Stream.ReadUInt32().FromEndian(endian); Unknown7 = Stream.ReadUInt32().FromEndian(endian); Unknown8 = Stream.ReadUInt32().FromEndian(endian); Unknown9 = Stream.ReadUInt32().FromEndian(endian); Unknown10 = Stream.ReadUInt32().FromEndian(endian); Unknown11 = Stream.ReadUInt32().FromEndian(endian); Unknown12 = Stream.ReadUInt32().FromEndian(endian); Unknown13 = Stream.ReadUInt32().FromEndian(endian); Unknown14 = Stream.ReadUInt32().FromEndian(endian); Unknown15 = Stream.ReadUInt32().FromEndian(endian); Unknown16 = Stream.ReadUInt32().FromEndian(endian); } finally { Stream.End(); } }
public static Compression.IHyoutaArchiveCompressionInfo?Deserialize(DuplicatableStream stream, long maxBytes, EndianUtils.Endianness endian) { if (maxBytes < 8) { stream.DiscardBytes(maxBytes); return(null); } ulong identifier = stream.ReadUInt64(EndianUtils.Endianness.BigEndian); switch (identifier) { case 0: // archive has compression, but this file is not compressed stream.DiscardBytes(maxBytes - 8); return(null); case DeflateSharpCompressionInfo.Identifier: return(DeflateSharpCompressionInfo.Deserialize(stream, maxBytes - 8, endian)); default: Console.WriteLine("Unknown compression type: " + identifier.ToString("x16")); stream.DiscardBytes(maxBytes - 8); return(null); } }
private bool LoadFile(DuplicatableStream headerStream, DuplicatableStream contentStream) { DuplicatableStream infile = headerStream.Duplicate(); contentFile = contentStream.Duplicate(); infile.Seek(0x00, SeekOrigin.Begin); string magic = infile.ReadAscii(4); if (magic != "FPS4") { Console.WriteLine("Not an FPS4 file!"); return(false); } Endian = Util.Endianness.BigEndian; FileCount = infile.ReadUInt32().FromEndian(Endian); HeaderSize = infile.ReadUInt32().FromEndian(Endian); // if header seems huge then we probably have assumed the wrong endianness if (HeaderSize > 0xFFFF) { Endian = Util.Endianness.LittleEndian; FileCount = FileCount.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); HeaderSize = HeaderSize.ToEndian(Util.Endianness.BigEndian).FromEndian(Endian); } FirstFileStart = infile.ReadUInt32().FromEndian(Endian); EntrySize = infile.ReadUInt16().FromEndian(Endian); ContentBitmask = new ContentInfo(infile.ReadUInt16().FromEndian(Endian)); Unknown2 = infile.ReadUInt32().FromEndian(Endian); ArchiveNameLocation = infile.ReadUInt32().FromEndian(Endian); infile.Position = ArchiveNameLocation; if (ArchiveNameLocation > 0) { ArchiveName = infile.ReadShiftJisNullterm(); } Alignment = FirstFileStart; Console.WriteLine("Content Bitmask: 0x" + ContentBitmask.Value.ToString("X4")); if (ContentBitmask.HasUnknownDataTypes) { Console.WriteLine("WARNING: Bitmask identifies unknown data types, data interpretation will probably be incorrect."); } Files = new List <FileInfo>((int)FileCount); for (uint i = 0; i < FileCount; ++i) { infile.Position = HeaderSize + (i * EntrySize); Files.Add(new FileInfo(infile, i, ContentBitmask, Endian, Util.GameTextEncoding.ASCII)); } FileLocationMultiplier = CalculateFileLocationMultiplier(); ShouldGuessFilesizeFromNextFile = !ContentBitmask.ContainsFileSizes && !ContentBitmask.ContainsSectorSizes && CalculateIsLinear(); infile.Dispose(); return(true); }
public CanDecompressAnswer CanDecompress(DuplicatableStream stream) { long pos = stream.Position; CanDecompressAnswer answer = stream.ReadAscii(4) == "TLZC" ? CanDecompressAnswer.Yes : CanDecompressAnswer.No; stream.Position = pos; return(answer); }
public void Close() { if (contentFile != null) { contentFile.Close(); contentFile = null; } }
public NUB(DuplicatableStream duplicatableStream, EndianUtils.Endianness?e) { Stream = duplicatableStream.Duplicate(); Stream.Position = 0; Header = new NubHeader(Stream, e); Endian = Header.Endian; Stream.Position = Header.StartOfEntries; Entries = Stream.ReadUInt32Array(Header.EntryCount, Endian); }
public override void Dispose() { if (Stream != null) { Stream.Close(); Stream.Dispose(); Stream = null; } }
public KnownFile(SHA1 hash, DuplicatableStream data, bool important = true, bool writeToBackup = true) { Hash = hash; AcquisitionMethods = new List <KnownFileAcquisitionMethod>() { new KnownFileAcquisitionFromStream(data, writeToBackup) }; Important = important; }
public override string ToString() { using (FPS4 fps4 = new FPS4(Stream.Duplicate())) using (DuplicatableStream txmvStream = fps4.GetChildByIndex(1).AsFile.DataStream.Duplicate()) using (FPS4 txmv = new FPS4(txmvStream.Duplicate())) using (DuplicatableStream txmStream = txmv.GetChildByIndex(0).AsFile.DataStream.Duplicate()) { TXM txm = new TXM(txmStream.Duplicate()); return(txm.TXMRegulars[0].Name); } }
private bool LoadFile(DuplicatableStream inputStream, EndianUtils.Endianness?endianParam, TextUtils.GameTextEncoding encoding) { DuplicatableStream stream = inputStream.Duplicate(); stream.Position = 0; EndianUtils.Endianness endian; if (endianParam == null) { uint magic = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.BigEndian); if (magic == 0x53453320) { endian = EndianUtils.Endianness.BigEndian; } else if (magic == 0x20334553) { endian = EndianUtils.Endianness.LittleEndian; } else { Console.WriteLine("Invalid magic: " + magic); return(false); } } else { endian = endianParam.Value; uint magic = stream.ReadUInt32(endian); if (magic != 0x53453320) { Console.WriteLine("Invalid magic: " + magic); return(false); } } this.Endian = endian; uint lengthOfFilenameSection = stream.ReadUInt32(endian); // probably? uint startOfFilenameSection = stream.ReadUInt32(endian); // probably? DataBegin = stream.ReadUInt32(endian); stream.Position = startOfFilenameSection; uint magicOfFilenameSection = stream.ReadUInt32(endian); FileCount = stream.ReadUInt32(endian); Filenames = new List <string>((int)FileCount); for (uint i = 0; i < FileCount; ++i) { Filenames.Add(stream.ReadSizedString(48, encoding).TrimNull()); } Data = stream; return(true); }
public void PrintData(EndianUtils.Endianness endian, Dictionary <uint, TSS.TSSEntry> inGameDic, List <ItemDat.ItemDatSingle> itemDataSorted, T8BTEMST.T8BTEMST enemies) { using (DuplicatableStream stream = Stream.Duplicate()) { stream.ReadUInt32().FromEndian(endian); // ? stream.ReadUInt32().FromEndian(endian); // ? stream.ReadUInt32Array(9, endian); stream.ReadUInt32().FromEndian(endian); // play time in frames, assuming 60 frames = 1 second stream.ReadUInt32().FromEndian(endian); // gald stream.DiscardBytes(4); // ? uint[] itemCounts = stream.ReadUInt32Array(3072, endian); uint[] itemBookBitfields = stream.ReadUInt32Array(3072 / 32, endian); stream.DiscardBytes(4); // ? stream.ReadUInt32Array(4, endian); // control modes for the four active party slots stream.ReadUInt32Array(3, endian); // strategies assigned to dpad directions stream.DiscardBytes(0x40); // ?? for (int i = 0; i < 8; ++i) { // custom strategy names // game seems to read these till null byte so this could totally be abused to buffer overflow... stream.ReadAscii(0x40); } stream.DiscardBytes(0xA84D0 - 0xA7360); // ? uint[] monsterBookBitfieldsScanned = stream.ReadUInt32Array(0x48 / 4, endian); stream.DiscardBytes(0xA8680 - 0xA8518); // ? uint[] monsterBookBitfieldsSeen = stream.ReadUInt32Array(0x48 / 4, endian); stream.DiscardBytes(0xA8928 - 0xA86C8); // ? uint collectorsBookIndex = 0; foreach (var item in itemDataSorted) { uint i = item.Data[(int)ItemDat.ItemData.ID]; if (item.Data[(int)ItemDat.ItemData.InCollectorsBook] > 0) { bool haveItem = ((itemBookBitfields[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveItem ? "Y" : "N") + (collectorsBookIndex) + ": " + inGameDic[item.NamePointer].StringEngOrJpn); ++collectorsBookIndex; } } uint monsterBookIndex = 0; foreach (var enemy in enemies.EnemyList) { uint i = enemy.InGameID; if (enemy.InMonsterBook > 0) { bool haveSeen = ((monsterBookBitfieldsSeen[i / 32] >> (int)(i % 32)) & 1) > 0; bool haveScanned = ((monsterBookBitfieldsScanned[i / 32] >> (int)(i % 32)) & 1) > 0; Console.WriteLine((haveSeen ? "Y" : "N") + (haveScanned ? "Y" : "N") + (monsterBookIndex) + ": " + inGameDic[enemy.NameStringDicID].StringEngOrJpn); ++monsterBookIndex; } } } }
public TrophyTrpFile(DuplicatableStream stream, EndianUtils.Endianness endian) { Filename = stream.ReadAscii(0x20).TrimNull(); Unknown1 = stream.ReadUInt32().FromEndian(endian); Start = stream.ReadUInt32().FromEndian(endian); Unknown3 = stream.ReadUInt32().FromEndian(endian); Length = stream.ReadUInt32().FromEndian(endian); Unknown5 = stream.ReadUInt32().FromEndian(endian); Unknown6 = stream.ReadUInt32().FromEndian(endian); Unknown7 = stream.ReadUInt32().FromEndian(endian); Unknown8 = stream.ReadUInt32().FromEndian(endian); }
private HyoutaPluginBase.FileContainer.INode ReturnAndCache(HyoutaPluginBase.FileContainer.INode node, string path, Version version) { if (node != null && path != null) { Directory.CreateDirectory(Path.GetDirectoryName(path)); using (FileStream fs = new FileStream(path, FileMode.Create)) { using (DuplicatableStream ds = node.AsFile.DataStream.Duplicate()) { StreamUtils.CopyStream(ds, fs, ds.Length); } } } return(node); }
private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { infile.Dispose(); } infile = null; toc_string_table = null; disposedValue = true; } }
public static DeflateSharpCompressionInfo?Deserialize(DuplicatableStream stream, long maxBytes, EndianUtils.Endianness endian) { // note: identifier has already been read if (maxBytes < 8) { stream.DiscardBytes(maxBytes); return(null); } ulong uncompressedFilesize = stream.ReadUInt64(endian); stream.DiscardBytes(maxBytes - 8); return(new DeflateSharpCompressionInfo(uncompressedFilesize)); }
public ScenarioDatEntry(DuplicatableStream data, uint FilesOffset) { Offset = data.ReadUInt32().SwapEndian(); FilesizeCompressed = data.ReadUInt32().SwapEndian(); FilesizeUncompressed = data.ReadUInt32().SwapEndian(); if (FilesizeCompressed > 0) { DataStream = new PartialStream(data, Offset + FilesOffset, FilesizeCompressed); } else { DataStream = null; } }
public static List <MainDolString> ReadElfStringsJp(DuplicatableStream filestream) { IRomMapper dol = new Ps3ElfMapper(); var stream = filestream.CopyToMemory(); var data = new List <MainDolString>(); ReadStringsInBlocks(data, dol, stream, 0x842DF4, 0x0A00, 0x14, 1, true); // battle field names? ReadStringsInBlocks(data, dol, stream, 0x8437F8, 0x0244, 0x04, 1, true); // menu strings ReadStringsInBlocks(data, dol, stream, 0x843A7C, 0x006C, 0x04, 1, true); // menu strings ReadStringsInBlocks(data, dol, stream, 0x845068, 0x083C, 0x04, 1, true); // menu strings for (int i = 0; i < 4; ++i) { data.Add(new MainDolString(0, 0, null, 0)); // JP and US desync here because of extra strings in US, compensate } ReadStringsInBlocks(data, dol, stream, 0x8458A4, 0x0714, 0x04, 1, true); // menu strings ReadStringsInBlocks(data, dol, stream, 0x845FD4, 0x151C, 0x1C, 4, true); // equipment effects ReadStringsInBlocks(data, dol, stream, 0x8475EC, 0x0074, 0x04, 1, true); // attack types ReadStringsInBlocks(data, dol, stream, 0x847660, 0x0200, 0x08, 1, true); // cooking effects ReadStringsInBlocks(data, dol, stream, 0x847858, 0x044C, 0x14, 2, true); // item traits ReadStringsInBlocks(data, dol, stream, 0x847CAC, 0x004C, 0x04, 1, true); // gem names ReadStringsInBlocks(data, dol, stream, 0x847D08, 0x00C0, 0x10, 4, true); // tutorials short ReadStringsInBlocks(data, dol, stream, 0x847DC8, 0x0EA0, 0x20, 7, true); // tutorials long ReadStringsInBlocks(data, dol, stream, 0x848C68, 0x0594, 0x1C, 7, true); // tutorials long ReadStringsInBlocks(data, dol, stream, 0x8491FC, 0x01F0, 0x08, 1, true); // books ReadStringsInBlocks(data, dol, stream, 0x8493EC, 0x00B4, 0x04, 1, true); // books [synopsis] ReadStringsInBlocks(data, dol, stream, 0x8494A0, 0x0BB8, 0x0C, 1, true); // books [sidequests] ReadStringsInBlocks(data, dol, stream, 0x84A058, 0x094C, 0x1C, 2, true); // discoveries ReadStringsInBlocks(data, dol, stream, 0x84A9A8, 0x0520, 0x04, 1, true); // enemy descriptions ReadStringsInBlocks(data, dol, stream, 0x84C20C, 0x1464, 0x24, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x84D670, 0x2154, 0x24, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x84F7C4, 0x02F4, 0x1C, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x84FAB8, 0x13D8, 0x28, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x850E90, 0x14AC, 0x24, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x85233C, 0x071C, 0x1C, 2, true); // items ReadStringsInBlocks(data, dol, stream, 0x852A58, 0x1770, 0x18, 2, true); // valuable items ReadStringsInBlocks(data, dol, stream, 0x8541C8, 0x024C, 0x0C, 2, true); // grade shop ReadStringsInBlocks(data, dol, stream, 0x854450, 0x2370, 0x24, 3, true); // requests ReadStringsInBlocks(data, dol, stream, 0x856800, 0x6670, 0x58, 3, true); // artes ReadStringsInBlocks(data, dol, stream, 0x85CF20, 0x0078, 0x0C, 2, true); // strategy ReadStringsInBlocks(data, dol, stream, 0x85CF98, 0x00A0, 0x08, 2, true); // strategy ReadStringsInBlocks(data, dol, stream, 0x87AA08, 0x0270, 0x0C, 2, true); // title effects (?) ReadStringsInBlocks(data, dol, stream, 0x85D0A8, 0x1D960, 0x70, 2, true); // titles return(data); //ReadStringsInBlocks( data, dol, stream, 0x5624E8, 0x0258, 0x14, 1 ); // debug strings //ReadStringsInBlocks( data, dol, stream, 0x562740, 0x0154, 0x04, 1 ); // debug strings //ReadStringsInBlocks( data, dol, stream, 0x570DAC, 0x0040, 0x04, 1 ); // menu strings // seem to no longer exist? }
public static DuplicatableStream ReadDuplicatableSubstream(this Stream stream, long bytecount) { DuplicatableStream ds = stream as DuplicatableStream; if (ds != null) { long p = ds.Position; PartialStream ps = new PartialStream(ds, p, bytecount); ds.Position = p + bytecount; return(ps); } else { return(new DuplicatableByteArrayStream(ReadBytes(stream, bytecount))); } }
public SHBP(DuplicatableStream duplicatableStream, EndianUtils.Endianness e = EndianUtils.Endianness.BigEndian) { using (DuplicatableStream s = duplicatableStream.Duplicate()) { uint magic = s.ReadUInt32(EndianUtils.Endianness.LittleEndian); if (magic != 0x50424853) { throw new Exception("wrong magic"); } uint count = s.ReadUInt32(e); Hashes = new List <uint>((int)count); for (uint i = 0; i < count; ++i) { Hashes.Add(s.ReadUInt32(e)); } } }
public static DuplicatableStream CreateConcatenatedStream(List <DuplicatableStream> streams) { if (streams.Count == 0) { return(EmptyStream.Instance); } var Streams = new List <DuplicatableStream>(streams.Count); var Offsets = new List <long>(Streams.Count); var InternalCanRead = true; var InternalCanSeek = true; var InternalCanWrite = true; long sum = 0; for (int i = 0; i < streams.Count; ++i) { DuplicatableStream s = streams[i].Duplicate(); s.ReStart(); long l = s.Length; if (l <= 0) { s.End(); s.Dispose(); continue; } sum += l; InternalCanRead = InternalCanRead && s.CanRead; InternalCanSeek = InternalCanSeek && s.CanSeek; InternalCanWrite = InternalCanWrite && s.CanWrite; s.End(); Streams.Add(s); Offsets.Add(sum); } if (Streams.Count == 0) { return(EmptyStream.Instance); } if (Streams.Count == 1) { return(Streams[0]); } return(new ConcatenatedStream(Streams, Offsets, InternalCanRead, InternalCanSeek, InternalCanWrite)); }
public static DuplicatableStream ReadDuplicatableSubstreamFromLocationAndReset(this Stream stream, long position, long bytecount) { long p = stream.Position; DuplicatableStream ds = stream as DuplicatableStream; if (ds != null) { return(new PartialStream(ds, p, bytecount)); } else { stream.Position = position; DuplicatableStream nds = new DuplicatableByteArrayStream(ReadBytes(stream, bytecount)); stream.Position = p; return(nds); } }
private static string?ReadString(DuplicatableStream s, uint maxBytes, EndianUtils.Endianness e) { if (maxBytes < 8) { // can't be a valid string s.DiscardBytes(maxBytes); return(null); } ulong rawlength = s.ReadUInt64(e); ulong length = (rawlength & 0x7ffffffffffffffful); bool hasOffset = (rawlength & 0x8000000000000000ul) > 0; if (hasOffset) { // format is 8 bytes length, then 8 bytes position of string in data if (maxBytes < 16) { // can't be valid s.DiscardBytes(maxBytes - 8); return(null); } ulong offset = s.ReadUInt64(e); long p = s.Position + (maxBytes - 16); s.Position = (long)offset; string str = s.ReadSizedString((long)length, TextUtils.GameTextEncoding.UTF8); s.Position = p; return(str); } else { // format is 8 bytes length, then [number read] bytes string uint restBytes = maxBytes - 8; if (length > restBytes) { // can't be a valid string s.DiscardBytes(restBytes); return(null); } string str = s.ReadSizedString((long)length, TextUtils.GameTextEncoding.UTF8); s.DiscardBytes(restBytes - length); return(str); } }