public static AssetReference Read(ExtendedBinaryReader br) { string assetPath = br.ReadNullTerminatedString(); byte[] GUID = br.ReadBytes(16); int type = br.ReadInt32(); string filePath = br.ReadNullTerminatedString(); return(new AssetReference(assetPath: assetPath, GUID: GUID, type: type, filePath: filePath)); }
public override void Load(ExtendedBinaryReader reader, bool keepOpen = false) { string header = reader.ReadNullTerminatedString(); reader.FixPadding(16); uint textureOffset = reader.ReadUInt32(); uint textureCount = reader.ReadUInt32(); int layerOffset = reader.ReadInt32(); int layerCount = reader.ReadInt32(); int unknownOffset = reader.ReadInt32(); int unknownCount = reader.ReadInt32(); uint unknown28 = reader.ReadUInt32(); uint unknown2C = reader.ReadUInt32(); string projectDir = reader.ReadStringElsewhere(); uint unknown34 = reader.ReadUInt32(); uint unknown38 = reader.ReadUInt32(); uint unknown3C = reader.ReadUInt32(); reader.JumpTo(textureOffset); for (int i = 0; i < textureCount; ++i) { Textures.Add(new MATexture(reader)); } reader.JumpTo(layerOffset); for (int i = 0; i < layerCount; ++i) { Layers.Add(new MALayer(reader)); } }
public override void Load(Stream fileStream) { // Header var reader = new ExtendedBinaryReader(fileStream); // Apparently SEGA doesn't even do signature checking (try loading an AR in-game // with the first 0xC bytes set to 0, it works just fine), so why should we? reader.JumpAhead(0xC); Padding = reader.ReadUInt32(); // Data while (fileStream.Position < fileStream.Length) { reader.Offset = (uint)fileStream.Position; uint dataEndOffset = reader.ReadUInt32(); uint dataLength = reader.ReadUInt32(); uint dataStartOffset = reader.ReadUInt32(); uint unknown1 = reader.ReadUInt32(); uint unknown2 = reader.ReadUInt32(); string name = reader.ReadNullTerminatedString(); reader.JumpTo(dataStartOffset, false); var data = reader.ReadBytes((int)dataLength); reader.JumpTo(dataEndOffset, false); var file = new ArchiveFile() { Name = name, Data = data }; Data.Add(file); } }
public NXNN ReadNodeNames(ExtendedBinaryReader reader, long pos) { NodeTree = new NXNN() { TreeNode = new string(reader.ReadChars(4)), NodeLength = reader.ReadUInt32() }; pos = reader.BaseStream.Position; //Save Position reader.JumpTo(reader.ReadUInt32() + 4, false); var nodeCount = reader.ReadUInt32(); reader.JumpTo(reader.ReadUInt32(), false); for (int i = 0; i < nodeCount; i++) { NodeTree node = new NodeTree(); node.NodeIndex = reader.ReadUInt32(); var nameOffset = reader.ReadUInt32(); long nodePos = reader.BaseStream.Position; //Save Position reader.JumpTo(nameOffset, false); node.NodeName = reader.ReadNullTerminatedString(); reader.JumpTo(nodePos); NodeTree.Nodes.Add(node); } reader.JumpTo(pos); reader.JumpAhead(NodeTree.NodeLength); return(NodeTree); }
public NXTL ReadTextureList(ExtendedBinaryReader reader, long pos) { TextureList = new NXTL() { TextureListNode = new string(reader.ReadChars(4)), NodeLength = reader.ReadUInt32() }; pos = reader.BaseStream.Position; //Save Position reader.JumpTo(reader.ReadUInt32(), false); TextureList.TextureCount = reader.ReadUInt32(); uint textureListOffset = reader.ReadUInt32(); reader.JumpTo(textureListOffset, false); for (int i = 0; i < TextureList.TextureCount; i++) { reader.JumpAhead(0x4); uint textureNameOffset = reader.ReadUInt32(); long texturePos = reader.BaseStream.Position; //Save Position reader.JumpTo(textureNameOffset, false); TEXFILE tex = new TEXFILE(); tex.Filename = reader.ReadNullTerminatedString(); reader.JumpTo(texturePos); tex.Filters = reader.ReadUInt32(); reader.JumpAhead(0x8); TextureList.Textures.Add(tex); } reader.JumpTo(pos); reader.JumpAhead(TextureList.NodeLength); return(TextureList); }
public static string ReadEntry(ExtendedBinaryReader reader) { if (reader.BaseStream.Position < reader.BaseStream.Length) { return(reader.ReadNullTerminatedString()); } return(""); }
public override void Load(ExtendedBinaryReader reader, bool keepOpen = false) { // Check if file has a signature string sig = reader.ReadSignature(); if (sig == "STSC") { // Newer script format uint headerSize = reader.ReadUInt32(); Version = reader.ReadUInt32(); switch (Version) { case 4: // Date A Live: Twin Edition Rio Reincarnation (PSV) ScriptID = reader.ReadUInt16(); break; case 7: // Date A Live: Rio Reincarnation (PC) ScriptName = reader.ReadNullTerminatedString(); reader.JumpAhead((uint)(0x20 - (ScriptName.Length + 1))); reader.JumpAhead(12); ScriptID = reader.ReadUInt32(); break; } } else { // Older script format // Jump back as older scripts have much smaller headers reader.JumpBehind(4); ScriptID = reader.ReadUInt16(); } // Stupid workaround to find the end of the code segment reader.Offset = (uint)reader.BaseStream.Length; while (true) { byte opcode = reader.ReadByte(); if (opcode >= 0x94) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " There is no opcodes larger than 0x93!"); } // Check if its a known instruction if (STSCInstructions.DALRRInstructions[opcode] == null) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " This opcode is unknown!"); } var instruction = STSCInstructions.DALRRInstructions[opcode].Read(reader); Instructions.Add(instruction); if (reader.BaseStream.Position >= reader.Offset) { break; } } }
public NXEF ReadEffectList(ExtendedBinaryReader reader, long pos) { EffectList = new NXEF() { EffectNode = new string(reader.ReadChars(4)), NodeLength = reader.ReadUInt32() }; pos = reader.BaseStream.Position; //Save Position reader.JumpTo(reader.ReadUInt32() + 4, false); var effectTypeCount = reader.ReadUInt32(); var effectTypeOffset = reader.ReadUInt32(); var techiqueCount = reader.ReadUInt32(); var techniqueOffset = reader.ReadUInt32(); reader.JumpTo(effectTypeOffset, false); for (int i = 0; i < effectTypeCount; i++) { EFFFILE effFile = new EFFFILE(); effFile.Type = reader.ReadUInt32(); var jumpPoint = reader.ReadUInt32(); long effectPos = reader.BaseStream.Position; //Save Position reader.JumpTo(jumpPoint, false); effFile.Filename = reader.ReadNullTerminatedString(); reader.JumpTo(effectPos); EffectList.Effects.Add(effFile); } reader.JumpTo(techniqueOffset, false); for (int i = 0; i < techiqueCount; i++) { TECHNAME tech = new TECHNAME(); tech.Type = reader.ReadUInt32(); tech.NodeID = reader.ReadUInt32(); var jumpPoint = reader.ReadUInt32(); long techPos = reader.BaseStream.Position; //Save Position reader.JumpTo(jumpPoint, false); tech.Filename = reader.ReadNullTerminatedString(); reader.JumpTo(techPos); EffectList.Techs.Add(tech); } reader.JumpTo(pos); reader.JumpAhead(EffectList.NodeLength); return(EffectList); }
// TODO protected void LoadShadowArchive(ExtendedBinaryReader reader) { reader.JumpAhead(0x4); // Unknown, Seems to always be 0 uint fileSize = reader.ReadUInt32(); // File Size - 0xC uint magic = reader.ReadUInt32(); // Magic string ONEVersion = reader.ReadNullTerminatedString(); // Gets the version String reader.FixPadding(); // Aligns the reader uint fileCount = reader.ReadUInt32(); // File Count reader.JumpAhead(0x38 * 2 + 0x20); // Jump to the third/first entry bool isVersion6 = ONEVersion == "ONE Ver 0.60"; // Checks if its version is 0.60 int fileNameLength = isVersion6 ? 0x2C : 0x20; // The max file name size // Read File List var files = new FileEntry[FileEntryCount]; for (int i = 0; i < fileCount; i++) { var entry = new FileEntry(); entry.FileName = reader.ReadSignature( fileNameLength).Replace("\0", string.Empty); entry.UncompressedSize = reader.ReadUInt32(); entry.DataOffset = reader.ReadUInt32(); reader.JumpAhead(4); // Unknown, Seems to always be 1 if (!isVersion6) { reader.JumpAhead(0xC); // Unknown, Seems to always be 0 } files[i] = entry; } // Read File Data if (files.Length > 0) { reader.JumpTo(files[0].DataOffset + 0xC); for (int i = 0; i < fileCount; ++i) { // Compute the file's data length files[i].DataLength = ((i == fileCount - 1) ? fileSize + 0xC : files[i + 1].DataOffset) - files[i].DataOffset; var file = new ArchiveFile() { Name = files[i].FileName, Data = reader.ReadBytes( (int)files[i].DataLength) // TODO: Decompress file }; Data.Add(file); } } }
public void Read(ExtendedBinaryReader reader) { uint texNameOffset = reader.ReadUInt32(); TexFlags = reader.ReadUInt32(); uint texTypeOffset = reader.ReadUInt32(); // Unknown Value Check if (TexFlags != 0) { Console.WriteLine($"WARNING: Texture Flags != 0 ({TexFlags})"); } // Texture Name reader.JumpTo(texNameOffset, false); TextureName = reader.ReadNullTerminatedString(); // Texture Type reader.JumpTo(texTypeOffset, false); Type = reader.ReadNullTerminatedString(); }
// Methods public static void Read(HavokFile h, ExtendedBinaryReader reader) { // Header reader.JumpAhead(0x10); // A lot of this was gathered from the Max Havok exporter. byte bytesInPointer = reader.ReadByte(); reader.IsBigEndian = !reader.ReadBoolean(); byte reusePaddingOpt = reader.ReadByte(); byte emptyBaseClassOpt = reader.ReadByte(); // We jump around a lot here, but there's not really a much cleaner way to do it. reader.JumpTo(8, true); h.UserTag = reader.ReadUInt32(); h.ClassVersion = reader.ReadInt32(); reader.JumpAhead(4); uint sectionsCount = reader.ReadUInt32(); uint unknown1 = reader.ReadUInt32(); ulong padding1 = reader.ReadUInt64(); uint unknown2 = reader.ReadUInt32(); h.ContentsVersion = reader.ReadNullTerminatedString(); reader.JumpAhead(9); // Seems to be padding // Sections for (uint i = 0; i < sectionsCount; ++i) { string sectionName = new string(reader.ReadChars(0x10)); sectionName = sectionName.Replace("\0", string.Empty); // TODO reader.JumpAhead(0x20); } // Padding Checks if (padding1 != 0) { Console.WriteLine($"WARNING: Padding1 != 0 ({padding1})"); } // TODO throw new NotImplementedException(); }
public void Read(ExtendedBinaryReader reader, uint textureCount) { // Texture Offsets var textureOffsets = new uint[textureCount]; for (uint i = 0; i < textureCount; ++i) { textureOffsets[i] = reader.ReadUInt32(); } // Textures textures.Clear(); for (uint i = 0; i < textureCount; ++i) { reader.JumpTo(textureOffsets[i], false); textures.Add(new GensTexture( reader.ReadNullTerminatedString())); } }
public NinjaTextureList ReadNinjaTextureList(ExtendedBinaryReader reader, long pos) { NinjaTextureList = new NinjaTextureList() { NodeName = new string(reader.ReadChars(4)) }; uint NodeLength = reader.ReadUInt32(); pos = reader.BaseStream.Position; //Save Position uint NodeOffset = reader.ReadUInt32(); reader.JumpTo(NodeOffset, false); uint TextureCount = reader.ReadUInt32(); uint TextureListOffset = reader.ReadUInt32(); reader.JumpTo(TextureListOffset, false); for (int i = 0; i < TextureCount; i++) { uint Unknown1 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?) uint TextureNameOffset = reader.ReadUInt32(); long currentPos = reader.BaseStream.Position; //Save Position reader.JumpTo(TextureNameOffset, false); NinjaTextureFile TextureFile = new NinjaTextureFile() { TextureName = reader.ReadNullTerminatedString() }; reader.JumpTo(currentPos, true); TextureFile.Filters = reader.ReadUInt32(); uint Unknown2 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?) uint Unknown3 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?) NinjaTextureList.TextureFiles.Add(TextureFile); } reader.JumpTo(pos, true); reader.JumpAhead(NodeLength); return(NinjaTextureList); }
public NinjaNodeNameList ReadNinjaNodeNameList(ExtendedBinaryReader reader, long pos) { NinjaNodeNameList = new NinjaNodeNameList() { NodeName = new string(reader.ReadChars(4)) }; uint NodeLength = reader.ReadUInt32(); pos = reader.BaseStream.Position; //Save Position uint NodeOffset = reader.ReadUInt32(); reader.JumpTo(NodeOffset, false); uint Unknown1 = reader.ReadUInt32(); //Padding? uint NodeTableCount = reader.ReadUInt32(); uint NodeTableOffset = reader.ReadUInt32(); reader.JumpTo(NodeTableOffset, false); for (int i = 0; i < NodeTableCount; i++) { NinjaNodeName NodeName = new NinjaNodeName() { ID = reader.ReadUInt32() }; uint NodeNameIndex = reader.ReadUInt32(); long currentPos = reader.BaseStream.Position; //Save Position reader.JumpTo(NodeNameIndex, false); NodeName.Name = reader.ReadNullTerminatedString(); reader.JumpTo(currentPos, true); NinjaNodeNameList.NinjaNodeNames.Add(NodeName); } reader.JumpTo(pos, true); reader.JumpAhead(NodeLength); return(NinjaNodeNameList); }
public NinjaEffectList ReadNinjaEffectList(ExtendedBinaryReader reader, long pos) { NinjaEffectList = new NinjaEffectList() { NodeName = new string(reader.ReadChars(4)) }; uint NodeLength = reader.ReadUInt32(); pos = reader.BaseStream.Position; //Save Position uint NodeOffset = reader.ReadUInt32(); reader.JumpTo(NodeOffset, false); uint Unknown1 = reader.ReadUInt32(); //Seems to always be 0 (at least in XN*s)? (Padding?) uint EffectTypeCount = reader.ReadUInt32(); uint EffectTypeOffset = reader.ReadUInt32(); uint TechniqueCount = reader.ReadUInt32(); uint TechniqueOffset = reader.ReadUInt32(); uint TechniqueIDXCount = reader.ReadUInt32(); uint TechniqueIDXOffset = reader.ReadUInt32(); //Effect Files reader.JumpTo(EffectTypeOffset, false); for (int i = 0; i < EffectTypeCount; i++) { NinjaEffectFile EffectFile = new NinjaEffectFile() { Type = reader.ReadUInt32() }; uint EffectFilenameOffset = reader.ReadUInt32(); long currentPos = reader.BaseStream.Position; //Save Position reader.JumpTo(EffectFilenameOffset, false); EffectFile.Filename = reader.ReadNullTerminatedString(); reader.JumpTo(currentPos, true); NinjaEffectList.EffectFiles.Add(EffectFile); } //Effect List reader.JumpTo(TechniqueOffset, false); for (int i = 0; i < TechniqueCount; i++) { NinjaEffectTechnique Technique = new NinjaEffectTechnique() { Type = reader.ReadUInt32(), ID = reader.ReadUInt32() }; uint TechniqueNameOffset = reader.ReadUInt32(); long currentPos = reader.BaseStream.Position; //Save Position reader.JumpTo(TechniqueNameOffset, false); Technique.TechniqueName = reader.ReadNullTerminatedString(); reader.JumpTo(currentPos, true); NinjaEffectList.Techniques.Add(Technique); } //Technique IDX (not sure what this is for) reader.JumpTo(TechniqueIDXOffset, false); for (int i = 0; i < TechniqueIDXCount; i++) { NinjaEffectList.TechniqueIDX.Add(reader.ReadUInt16()); } reader.JumpTo(pos, true); reader.JumpAhead(NodeLength); return(NinjaEffectList); }
public override void Parse(ExtendedBinaryReader br) { base.Parse(br); Version = br.ReadByte(); Flags = br.ReadUInt24(); TimeScale = br.ReadUInt32(); QualityEntryCount = br.ReadByte(); QualitySegmentUrlModifiers = Enumerable.Range(0, QualityEntryCount).Select(i => br.ReadNullTerminatedString()).ToArray(); FragmentRunEntryCount = br.ReadUInt32(); FragmentRunEntryTable = new FragmentRunEntry[FragmentRunEntryCount]; for (uint i = 0; i < FragmentRunEntryCount; i++) FragmentRunEntryTable[i] = FragmentRunEntry.Parse(br); }
/* * public TypeTree(TypeTree parent, uint format, int version, bool isArray, int size, int index, int flags, string type, string name) * { * this.parent = parent; * this.format = format; * * this.version = version; * this.isArray = isArray; * this.size = size; * this.index = index; * this.flags = flags; * this.type = type; * this.name = name; * } */ public static TypeTreeNode ReadTypeTree(uint format, ExtendedBinaryReader buf) { TypeTreeNode root = new TypeTreeNode(); if (format == 10 || format >= 12) { int nodesCount = buf.ReadInt32(); int stringBufferBytes = buf.ReadInt32(); int nodesize = format >= 19 ? 32 : 24; buf.BaseStream.Seek(nodesize * nodesCount, SeekOrigin.Current); byte[] stringData = buf.ReadBytes(stringBufferBytes); buf.BaseStream.Seek(-(nodesize * nodesCount + stringBufferBytes), SeekOrigin.Current); Stack <TypeTreeNode> stack = new Stack <TypeTreeNode>(); stack.Push(root); using (var stringReader = new ExtendedBinaryReader(new MemoryStream(stringData))) { for (int i = 0; i < nodesCount; i++) { short version = buf.ReadInt16(); byte depth = buf.ReadByte(); bool isArray = buf.ReadBoolean(); ushort typeIndex = buf.ReadUInt16(); string typeStr; if (buf.ReadUInt16() == 0) { stringReader.BaseStream.Position = typeIndex; typeStr = stringReader.ReadNullTerminatedString(); } else { typeStr = baseStrings.ContainsKey(typeIndex) ? baseStrings[typeIndex] : typeIndex.ToString(); } ushort nameIndex = buf.ReadUInt16(); string nameStr; if (buf.ReadUInt16() == 0) { stringReader.BaseStream.Position = nameIndex; nameStr = stringReader.ReadNullTerminatedString(); } else { nameStr = baseStrings.ContainsKey(nameIndex) ? baseStrings[nameIndex] : nameIndex.ToString(); } int size = buf.ReadInt32(); int index = buf.ReadInt32(); int flags = buf.ReadInt32(); ulong refTypeHash = 0; if (format >= 19) { refTypeHash = buf.ReadUInt64(); } TypeTreeNode t; if (depth == 0) { t = root; } else { while (stack.Count > depth) { stack.Pop(); } t = new TypeTreeNode(); stack.Peek().children.Add(t); stack.Push(t); } t.version = version; t.isArray = isArray; t.type = typeStr; t.name = nameStr; t.size = size; t.index = index; t.flags = flags; t.refTypeHash = refTypeHash; } } buf.BaseStream.Seek(stringBufferBytes, SeekOrigin.Current); } else { root.type = buf.ReadNullTerminatedString(); root.name = buf.ReadNullTerminatedString(); root.size = buf.ReadInt32(); root.index = buf.ReadInt32(); root.isArray = buf.ReadBoolean(); root.version = buf.ReadInt32(); root.flags = buf.ReadInt32(); int childCount = buf.ReadInt32(); for (int i = 0; i < childCount; i++) { root.children.Add(TypeTreeNode.ReadTypeTree(format, buf)); } } return(root); }
public override void Load(Stream fileStream) { // Header var reader = new ExtendedBinaryReader(fileStream, true); var entries = new List <FileEntry>(); uint sig = reader.ReadUInt32(); if (sig != Signature) { throw new InvalidSignatureException( Signature.ToString("X"), sig.ToString("X")); } uint fileTableOffset = reader.ReadUInt32(); uint fileTableLength = reader.ReadUInt32(); uint fileDataOffset = reader.ReadUInt32(); uint unknown5 = reader.ReadUInt32(); uint unknown6 = reader.ReadUInt32(); uint unknown7 = reader.ReadUInt32(); uint unknown8 = reader.ReadUInt32(); // File/Directory Entries long fileTableEnd = (fileTableOffset + fileTableLength); reader.JumpTo(fileTableOffset); while (fileStream.Position < fileTableEnd) { bool isDirectory = reader.ReadBoolean(); byte padding1 = reader.ReadByte(); if (padding1 != 0) { fileStream.Position -= 2; // go bacc break; } var fileEntry = new FileEntry() { IsDirectory = isDirectory, FileNameOffset = reader.ReadUInt16(), DataOffset = reader.ReadUInt32(), DataLength = reader.ReadUInt32(), DataUncompressedSize = reader.ReadUInt32() }; entries.Add(fileEntry); } // Entry Names uint fileNamesOffset = (uint)fileStream.Position; foreach (var entry in entries) { reader.JumpTo(fileNamesOffset + entry.FileNameOffset); entry.Name = reader.ReadNullTerminatedString(); } // Entry Data ArchiveDirectory dir = null; for (int i = 0; i < entries.Count; ++i) { var entry = entries[i]; // Directory if (entry.IsDirectory) { // Generate a HedgeLib directory entry if (i == 0) { continue; } if (entry.DataOffset >= i) { throw new Exception("Entry DataOffset is invalid"); } var dirEntry = new ArchiveDirectory(entry.Name); if (entry.DataOffset != 0) { var parentEntry = entries[(int)entry.DataOffset]; dirEntry.Parent = parentEntry.Directory; } if (dirEntry.Parent == null) { Data.Add(dirEntry); } else { dirEntry.Parent.Data.Add(dirEntry); } dir = entry.Directory = dirEntry; } // File else { if (dir == null) { throw new Exception("Tried to read a file not in a directory!"); } var data = new byte[entry.DataUncompressedSize]; int offset = 0, size = (int)entry.DataUncompressedSize; reader.JumpTo(entry.DataOffset + 2); using (var gzipStream = new DeflateStream(fileStream, CompressionMode.Decompress, true)) { while (offset < size) { offset += gzipStream.Read(data, offset, (size - offset)); } } // Generate a HedgeLib file entry dir.Data.Add(new ArchiveFile(entry.Name, data)); } } }
private static SetObject ReadObject(ExtendedBinaryReader reader, SetObjectType objTemplate, string objType, SOBJType type, bool rawDataMode = false) // true = full, false = only remaining bytes { // For some reason these separate values are saved as one uint rather than two ushorts. // Because of this, the values are in a different order depending on endianness, and // this is the easiest known way to read them. uint unknownValue = reader.ReadUInt32(); ushort unknown1 = (ushort)((unknownValue >> 16) & 0xFFFF); ushort objID = (ushort)(unknownValue & 0xFFFF); var obj = new SetObject() { ObjectType = objType, ObjectID = objID }; uint unknown2 = reader.ReadUInt32(); uint unknown3 = reader.ReadUInt32(); float unknown4 = reader.ReadSingle(); float rangeIn = reader.ReadSingle(); float rangeOut = reader.ReadSingle(); uint parent = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0; uint transformsOffset = reader.ReadUInt32(); uint transformCount = reader.ReadUInt32(); uint unknown5 = reader.ReadUInt32(); uint unknown6 = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0; uint unknown7 = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0; // Call me crazy, but I have a weird feeling these values aren't JUST padding if (unknown3 != 0 || unknown5 != 0 || unknown6 != 0 || unknown7 != 0) { Console.WriteLine("WARNING: Not padding?! ({0},{1},{2},{3})", unknown3, unknown5, unknown6, unknown7); } // Add custom data to object obj.CustomData.Add("Unknown1", new SetObjectParam(typeof(ushort), unknown1)); obj.CustomData.Add("Unknown2", new SetObjectParam(typeof(uint), unknown2)); obj.CustomData.Add("Unknown3", new SetObjectParam(typeof(uint), unknown3)); obj.CustomData.Add("Unknown4", new SetObjectParam(typeof(float), unknown4)); obj.CustomData.Add("RangeIn", new SetObjectParam(typeof(float), rangeIn)); obj.CustomData.Add("RangeOut", new SetObjectParam(typeof(float), rangeOut)); if (type == SOBJType.LostWorld) { obj.CustomData.Add("Parent", new SetObjectParam(typeof(uint), parent)); } // Skip loading parameters if template doesn't exist if (objTemplate != null) { // Get Raw Byte Length var rawDataLenExtra = objTemplate.GetExtra("RawByteLength"); long paramBegin = reader.BaseStream.Position; int rawLength = 0; if (rawDataLenExtra != null && !string.IsNullOrEmpty(rawDataLenExtra.Value)) { int.TryParse(rawDataLenExtra.Value, out rawLength); } // Read all the data then return to beginning if (rawDataMode == true && rawLength != 0) { obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]), reader.ReadBytes(rawLength))); reader.JumpTo(paramBegin); } // Parameters foreach (var param in objTemplate.Parameters) { // For compatibility with SonicGlvl templates. if (param.Name == "Unknown1" || param.Name == "Unknown2" || param.Name == "Unknown3" || param.Name == "RangeIn" || param.Name == "RangeOut" || param.Name == "Parent") { continue; } // Read Special Types/Fix Padding if (param.DataType == typeof(uint[])) { // Data Info reader.FixPadding(4); uint arrOffset = reader.ReadUInt32(); uint arrLength = reader.ReadUInt32(); uint arrUnknown = reader.ReadUInt32(); long curPos = reader.BaseStream.Position; // Data var arr = new uint[arrLength]; reader.JumpTo(arrOffset, false); for (uint i = 0; i < arrLength; ++i) { arr[i] = reader.ReadUInt32(); } obj.Parameters.Add(new SetObjectParam(param.DataType, arr)); reader.BaseStream.Position = curPos; continue; } else if (param.DataType == typeof(string)) { // Data Info uint strOffset = reader.ReadUInt32(); uint strUnknown = reader.ReadUInt32(); string str = null; // Data if (strOffset != 0) { long curPos = reader.BaseStream.Position; reader.JumpTo(strOffset, false); str = reader.ReadNullTerminatedString(); reader.BaseStream.Position = curPos; } obj.Parameters.Add(new SetObjectParam(param.DataType, str)); continue; } else if (param.DataType == typeof(float) || param.DataType == typeof(int) || param.DataType == typeof(uint)) { reader.FixPadding(4); } else if (type == SOBJType.LostWorld && param.DataType == typeof(Vector3)) { reader.FixPadding(16); } // Read Data var objParam = new SetObjectParam(param.DataType, reader.ReadByType(param.DataType)); obj.Parameters.Add(objParam); } if (rawDataMode == false) { long knownParamLength = (reader.BaseStream.Position - paramBegin); long remainingBytes = (rawLength - knownParamLength); obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]), reader.ReadBytes((int)remainingBytes))); } } // Transforms uint childCount = transformCount - 1; obj.Children = new SetObjectTransform[childCount]; reader.JumpTo(transformsOffset, false); obj.Transform = ReadTransform(reader, type == SOBJType.LostWorld); for (uint i = 0; i < childCount; ++i) { obj.Children[i] = ReadTransform(reader, type == SOBJType.LostWorld); } return(obj); }
public const uint TAGMagic = 0x30474154; // "TAG0" in little-endian // Methods public static void Read(HavokFile h, ExtendedBinaryReader reader) { var fs = reader.BaseStream; long pos = fs.Position; long endPos = pos; var types = new List <string>(); reader.IsBigEndian = true; while (pos < fs.Length) { uint size = reader.ReadUInt32(); string type = new string(reader.ReadChars(4)); bool isParam = (((size & 0xC0000000) >> 24) == 0x40); // Remove the param marker from the beginning of the size if (isParam) { size &= 0xFFFFFF; } size -= 8; pos = fs.Position; endPos = pos + size; Console.WriteLine("{0}: \"{1}\"", (isParam) ? "Parameter" : "Section", type); // Read based on type switch (type) { // SDK Version case "SDKV": h.ContentsVersion = new string(reader.ReadChars((int)size)); Console.WriteLine($"Contents Version: {h.ContentsVersion}"); break; case "DATA": ReadDATASection(); break; // Type Strings case "TSTR": { Console.WriteLine(); while (fs.Position < endPos) { string t = reader.ReadNullTerminatedString(); if (string.IsNullOrEmpty(t)) { continue; } Console.WriteLine(t); types.Add(t); // TODO } Console.WriteLine(); break; } // Type Names (??) case "TNAM": { uint unknown1 = reader.ReadUInt32(); // TODO break; } // Format Strings case "FSTR": { Console.WriteLine(); while (fs.Position < endPos) { string t = reader.ReadNullTerminatedString(); if (string.IsNullOrEmpty(t)) { continue; } Console.WriteLine(t); // TODO } Console.WriteLine(); // TODO break; } } // TODO // Jump ahead to the next parameter if (isParam) { pos = endPos; if (fs.Position != pos) { reader.JumpTo(pos); } } } // Sub-Methods //HavokSection ReadSection() //{ // var section = new HavokSection(); // // TODO // return section; //} void ReadDATASection() { reader.IsBigEndian = false; // TODO ulong unknown1 = reader.ReadUInt64(); ulong unknown2 = reader.ReadUInt64(); ulong unknown3 = reader.ReadUInt64(); ulong unknown4 = reader.ReadUInt64(); ulong unknown5 = reader.ReadUInt64(); for (uint i = 0; i < unknown1; ++i) { string s = reader.ReadNullTerminatedString(); Console.WriteLine(s); } // TODO // Padding Checks if (unknown2 != 0) { Console.WriteLine($"WARNING: DATA Unknown2 != 0 ({unknown2})"); } reader.IsBigEndian = true; // TODO } }
public static ServerEntry Parse(ExtendedBinaryReader br) { return new ServerEntry { ServerBaseURL = br.ReadNullTerminatedString() }; }
public override void Parse(ExtendedBinaryReader br) { base.Parse(br); Version = br.ReadByte(); Flags = br.ReadUInt24(); BootstrapinfoVersion = br.ReadUInt32(); var b = br.ReadByte(); Profile = (new byte[] { 0x80, 0x40 }).Select(i => (i & b) != 0).ToArray(); Live = (0x02 & b) != 0; Update = (0x01 & b) != 0; Reserved = (new byte[] { 0x08, 0x04, 0x02, 0x01 }).Select(i => (i & b) != 0).ToArray(); TimeScale = br.ReadUInt32(); CurrentMediaTime = br.ReadUInt64(); SmpteTimeCodeOffset = br.ReadUInt64(); MovieIdentifier = br.ReadNullTerminatedString(); ServerEntryCount = br.ReadByte(); ServerEntryTable = new ServerEntry[ServerEntryCount]; for (int i = 0; i < ServerEntryCount; i++) ServerEntryTable[i] = ServerEntry.Parse(br); QualityEntryCount = br.ReadByte(); QualityEntryTable = new QualityEntry[QualityEntryCount]; for (int i = 0; i < QualityEntryCount; i++) QualityEntryTable[i] = QualityEntry.Parse(br); DrmData = br.ReadNullTerminatedString(); MetaData = br.ReadNullTerminatedString(); SegmentRunTableCount = br.ReadByte(); SegmentRunTableEntries = new SegmentRunTableBox[SegmentRunTableCount]; for (int i = 0; i < SegmentRunTableCount; i++) { SegmentRunTableEntries[i] = new SegmentRunTableBox(); SegmentRunTableEntries[i].Parse(br); } FragmentRunTableCount = br.ReadByte(); FragmentRunTableEntries = new FragmentRunTableBox[FragmentRunTableCount]; for (int i = 0; i < FragmentRunTableCount; i++) { FragmentRunTableEntries[i] = new FragmentRunTableBox(); FragmentRunTableEntries[i].Parse(br); } }
public static QualityEntry Parse(ExtendedBinaryReader br) { return new QualityEntry { QualitySegmentUrlModifier = br.ReadNullTerminatedString() }; }
private AssetsFile(string path) { this.path = path; buf = new ExtendedBinaryReader(File.OpenRead(path)); basepath = Path.GetDirectoryName(path); buf.endian = EndianType.BigEndian; metadata_size = buf.ReadUInt32(); file_size = buf.ReadUInt32(); format = buf.ReadUInt32(); data_offset = buf.ReadUInt32(); if (format >= 9 && buf.ReadUInt32() == 0) { fileEndianType = EndianType.LittleEndian; } if (format >= 22) { metadata_size = buf.ReadUInt32(); file_size = buf.ReadInt64(); data_offset = buf.ReadInt64(); buf.BaseStream.Seek(8, SeekOrigin.Current); // Unknown value } buf.endian = fileEndianType; string versionString = buf.ReadNullTerminatedString(); versionString = versionString.Replace('p', '.'); versionString = versionString.Replace('f', '.'); version = new Version(versionString); platform = buf.ReadInt32(); buf.endian = EndianType.LittleEndian; typeMetaData = new TypeMetaData(format, buf); if (format >= 7 && format < 14) { longObjectIDs = buf.ReadInt32() != 0; } // Read obejct info table int objectCount = buf.ReadInt32(); // Save position for saving file objectsIndexOffset = buf.Position; var assetsDict = new Dictionary <long, AssetInfo>(objectCount); for (int i = 0; i < objectCount; i++) { var assetInfo = new AssetInfo(); assetInfo.asset = this; assetInfo.pathID = ReadPathID(); assetInfo.dataOffset = format >= 22 ? buf.ReadInt64() : buf.ReadUInt32(); assetInfo.size = buf.ReadUInt32(); assetInfo.typeID = buf.ReadInt32(); if (format < 16) { assetInfo.classID = buf.ReadUInt16(); } else { assetInfo.classID = typeMetaData.ClassIDs[assetInfo.typeID].classID; } if (format < 16) { assetInfo.isDestroyed = buf.ReadUInt16() != 0; } if (format == 15 || format == 16) { assetInfo.stripped = buf.ReadByte(); } assetsDict.Add(assetInfo.pathID, assetInfo); } assets = assetsDict; if (format >= 11) { int scriptCount = buf.ReadInt32(); scriptTypes = new List <ScriptType>(scriptCount); for (int i = 0; i < scriptCount; i++) { var add = new ScriptType { index = buf.ReadInt32(), ID = ReadPathID() }; scriptTypes.Add(add); } } if (format >= 6) { int referenceCount = buf.ReadInt32(); references = new List <AssetReference>(referenceCount); for (int i = 0; i < referenceCount; i++) { references.Add(AssetReference.Read(buf)); } } }