public override void ParseFileBytes(byte[] fileBytes) { int offset = 0; FileInfo fileInfo = new FileInfo(Path); // read header _header = FileTools.ByteArrayToStructure <Header>(fileBytes, ref offset); if (_header.MagicWord != FileMagicWord) { return; // todo add exception } // read file entries int bytesRemaining = (int)(fileInfo.Length - offset); int structSize = Marshal.SizeOf(typeof(FileEntryStruct)); if (bytesRemaining % structSize != 0) { // todo: add fail/warning? } int fileEntryCount = bytesRemaining / structSize; _fileEntryStructs = FileTools.ByteArrayToArray <FileEntryStruct>(fileBytes, ref offset, fileEntryCount); // process file entries foreach (FileEntryStruct fileEntryStruct in _fileEntryStructs) { Files.Add(new FileEntry(fileEntryStruct) { Pack = this }); } }
public void ParseFileBytes(byte[] fileBytes, bool debugOutputLoadingProgress) { // sanity check if (fileBytes == null) { throw new ArgumentNullException("fileBytes", "File bytes cannot be null!"); } Character = new UnitObject(debugOutputLoadingProgress); int byteOffset = 0; // main file header FileHeader fileHeader = FileTools.ByteArrayToStructure <FileHeader>(fileBytes, ref byteOffset); // file header checks if (fileHeader.MagicWord != FileMagicWord) { throw new Exceptions.UnexpectedMagicWordException(); } if (fileHeader.Version != RequiredVersion) { throw new Exceptions.NotSupportedFileVersionException(); } byteOffset = UnitObjectOffset; Character.ParseUnitObject(fileBytes, byteOffset, fileBytes.Length - byteOffset); }
/// <summary> /// Parses a level rules file bytes. /// </summary> /// <param name="fileBytes">The bytes of the level rules to parse.</param> public override void ParseFileBytes(byte[] fileBytes) { // sanity check if (fileBytes == null) { throw new ArgumentNullException("fileBytes", "File bytes cannot be null!"); } _xmlLevelRules = new XmlLevelRules(); int offset = 0; // file header checks UInt32 fileMagicWord = FileTools.ByteArrayToUInt32(fileBytes, ref offset); if (fileMagicWord != FileMagicWord) { throw new Exceptions.UnexpectedMagicWordException(); } UInt32 fileVersion = FileTools.ByteArrayToUInt32(fileBytes, ref offset); if (fileVersion != RequiredVersion) { throw new Exceptions.NotSupportedFileVersionException(); } // main file header _xmlLevelRules.FileHeader = FileTools.ByteArrayToStructure <LevelRulesHeader>(fileBytes, ref offset); LevelRulesHeader header = _xmlLevelRules.FileHeader; // static rules if (header.StaticRulesCount != 0 && header.StaticRulesFooterOffset != 0) { _xmlLevelRules.LevelRules = new LevelRule[header.StaticRulesCount]; int staticRulesFooterOffset = (int)header.StaticRulesFooterOffset; for (int i = 0; i < header.StaticRulesCount; i++) { int roomsCount = FileTools.ByteArrayToInt32(fileBytes, staticRulesFooterOffset); staticRulesFooterOffset += 8; int roomsOffset = FileTools.ByteArrayToInt32(fileBytes, staticRulesFooterOffset); staticRulesFooterOffset += 8; _xmlLevelRules.LevelRules[i] = new LevelRule { StaticRooms = FileTools.ByteArrayToArray <Room>(fileBytes, roomsOffset, roomsCount) }; offset += Marshal.SizeOf(typeof(Room)) * roomsCount + 16; _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].StaticRooms); } } else if (header.RandomRulesCount != 0 && header.RandomRulesFooterOffset != 0) { _xmlLevelRules.LevelRules = new LevelRule[header.RandomRulesCount]; // checked all files an no files have both static and random, so no chance of overwriting static above LevelRulesRandomFooter[] levelRulesFooters = FileTools.ByteArrayToArray <LevelRulesRandomFooter>(fileBytes, (int)header.RandomRulesFooterOffset, (int)header.RandomRulesCount); offset += Marshal.SizeOf(typeof(LevelRulesRandomFooter)) * (int)header.RandomRulesCount; for (int i = 0; i < header.RandomRulesCount; i++) { _xmlLevelRules.LevelRules[i] = new LevelRule { // get rule connector rooms ConnectorRooms = FileTools.ByteArrayToArray <Room>(fileBytes, (Int32)levelRulesFooters[i].ConnectorRuleOffset, (Int32)levelRulesFooters[i].ConnectorRoomCount), // then the actual level rules Rules = new Room[levelRulesFooters[i].RuleCount][] }; offset += Marshal.SizeOf(typeof(Room)) * (int)levelRulesFooters[i].ConnectorRoomCount; _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].ConnectorRooms); for (int j = 0; j < levelRulesFooters[i].RuleCount; j++) { _xmlLevelRules.LevelRules[i].Rules[j] = FileTools.ByteArrayToArray <Room>(fileBytes, (Int32)levelRulesFooters[i].RuleOffsets[j], levelRulesFooters[i].RoomCounts[j]); offset += Marshal.SizeOf(typeof(Room)) * levelRulesFooters[i].RoomCounts[j]; _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].Rules[j]); } } } // final debug check CT_Rule100 is corrupt or something - has extra bytes at end of it //Debug.Assert(offset == fileBytes.Length); }
/// <summary> /// Parses a level rules file bytes. /// </summary> /// <param name="fileBytes">The bytes of the level rules to parse.</param> public override void ParseFileBytes(byte[] fileBytes) { // sanity check if (fileBytes == null) { throw new ArgumentNullException("fileBytes", "File bytes cannot be null!"); } RoomDefinition = new RoomDefinitionStruct(); // file header checks int offset = 0; UInt32 fileMagicWord = FileTools.ByteArrayToUInt32(fileBytes, ref offset); if (fileMagicWord != FileMagicWord) { throw new Exceptions.UnexpectedMagicWordException(); } UInt32 fileVersion = FileTools.ByteArrayToUInt32(fileBytes, ref offset); if (fileVersion != RequiredVersion) { throw new Exceptions.NotSupportedFileVersionException(); } // main file header RoomDefinition.FileHeader = FileTools.ByteArrayToStructure <RoomDefinitionHeader>(fileBytes, ref offset); RoomDefinitionHeader header = RoomDefinition.FileHeader; // read UnknownStruct1 array offset = (int)header.Offset110; int count10C = header.Count10C; if (offset > 0 && count10C > 0) { RoomDefinition.UnknownStruct1Array = _ReadUnknownStruct1Array(fileBytes, ref offset, count10C); // FileTools.ByteArrayToArray<UnknownStruct1>(fileBytes, ref offset, count10C); } // read UnknownStruct2 array offset = (int)header.Offset120; int count118 = header.Count118; if (offset > 0 && count118 > 0) { RoomDefinition.UnknownStruct2Array = _ReadUnknownStruct2Array(fileBytes, ref offset, count118); // FileTools.ByteArrayToArray<UnknownStruct2>(fileBytes, ref offset, count118); } // read UnknownStruct3 arrays offset = (int)header.Offset288; int count29C = header.Count29C; int count298 = header.Count298; if (offset > 0 && count29C > 0 && count298 > 0) { RoomDefinition.UnknownStruct3Arrays = new UnknownStruct3[count29C][]; for (int i = 0; i < count29C; i++) { RoomDefinition.UnknownStruct3Arrays[i] = _ReadUnknownStruct3Array(fileBytes, ref offset, count298); // FileTools.ByteArrayToArray<UnknownStruct3>(fileBytes, ref offset, count298); } } // read UnknownStruct3 Int32 array offset = (int)header.Offset2A0; int count2A8 = header.Count2A8; if (offset > 0 && count2A8 > 0) { RoomDefinition.UnknownStruct3Int32Array = FileTools.ByteArrayToInt32Array(fileBytes, ref offset, count2A8); } // read room vertices array offset = (int)header.VerticesOffset; int vertexCount = header.VertexCount; if (offset > 0 && vertexCount > 0) { RoomDefinition.Vertices = _ReadVector3Array(fileBytes, ref offset, vertexCount); // FileTools.ByteArrayToArray<Vector3>(fileBytes, ref offset, vertexCount); } // read UnknownStruct5 array offset = (int)header.Offset278; int count280 = header.Count280; if (offset > 0 && count280 > 0) { RoomDefinition.UnknownStruct5Array = FileTools.ByteArrayToArray <UnknownStruct5>(fileBytes, ref offset, count280); } // read UnknownStruct6 array offset = (int)header.Offset130; int count12C = header.Count12C; if (offset > 0 && count12C > 0) { RoomDefinition.UnknownStruct6Array = FileTools.ByteArrayToArray <UnknownStruct6>(fileBytes, ref offset, count12C); } // read UnknownStruct7 array (not seen read like this - but it works) - has same structure (3xfloat) as UnknownStruct4 offset = (int)header.Offset178; int count174 = header.Count174; if (offset > 0 && count174 > 0) { RoomDefinition.UnknownStruct7Array = _ReadUnknownStruct7Vector3Array(fileBytes, ref offset, count174); // FileTools.ByteArrayToArray<Vector3>(fileBytes, ref offset, count174); } // read UnknownStruct8 array (not seen read like this - but it works) offset = (int)header.Offset188; int count184 = header.Count184; if (offset > 0 && count184 > 0) { RoomDefinition.UnknownStruct8Array = _ReadUnknownStruct7Array(fileBytes, ref offset, count184); // FileTools.ByteArrayToArray<UnknownStruct7>(fileBytes, ref offset, count184); } // read UnknownStruct9 array offset = (int)header.Offset168; int countUnknown7 = header.Count160; if (offset > 0 && countUnknown7 > 0) { RoomDefinition.UnknownStructFooter = FileTools.ByteArrayToArray <UnknownStruct5>(fileBytes, ref offset, countUnknown7); } // final debug check Debug.Assert(offset == fileBytes.Length); }
private void _ParseDataType(byte[] buffer) { int offset = 0; // header FileHeader fileHeader = FileTools.ByteArrayToStructure <FileHeader>(buffer, ref offset); if (fileHeader.FileToken != Token.Head) { throw new Exceptions.UnexpectedTokenException("Expected Head token but got 0x" + fileHeader.FileToken.ToString("X8")); } if (fileHeader.FileVersion != RequiredVersion) { throw new Exceptions.NotSupportedFileVersionException(RequiredVersion, fileHeader.FileVersion); } // Read the strings section StringsHeader stringsHeader = FileTools.ByteArrayToStructure <StringsHeader>(buffer, ref offset); if (stringsHeader.StringsToken != Token.Sect) { throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsHeader.StringsToken); } List <String> strings = new List <String>(); for (int i = 0; i < stringsHeader.StringsCount; i++) { strings.Add(FileTools.ByteArrayToStringASCII(buffer, offset)); offset += strings[i].Length + 1; // +1 for \0 } // String Details UInt32 stringsDetailsToken = FileTools.ByteArrayToUInt32(buffer, ref offset); if (stringsDetailsToken != Token.Sect) { throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsDetailsToken); } // Skip over the details struct because we don't need it. offset += stringsHeader.StringsCount * Marshal.SizeOf(typeof(StringDetailsStruct)); // Files Structure details UInt32 filesToken = FileTools.ByteArrayToUInt32(buffer, ref offset); if (filesToken != Token.Sect) { throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsDetailsToken); } FileDetails.AddRange(FileTools.ByteArrayToArray <FileEntryStruct>(buffer, ref offset, fileHeader.FileCount)); // The Files list is the public interface for (int i = 0; i < fileHeader.FileCount; i++) { PackFileEntry fileEntry = new FileEntry(FileDetails[i]) { Pack = this, Path = System.IO.Path.Combine(strings[FileDetails[i].DirectoryIndex], strings[FileDetails[i].NameIndex]), }; Files.Add(fileEntry); } HasIntegrity = true; }
private void _ParsePatchType(byte[] buffer) { int offset = 0; /* This reading/parsing stores all date merely to make it clear of the file structure. * Given we're not going to be using this much at all, this will do for now until we know * what all the unknown fields are. */ // header PatchFileHeader fileHeader = FileTools.ByteArrayToStructure <PatchFileHeader>(buffer, ref offset); if (fileHeader.EndToken != Token.PatchSect) { throw new Exceptions.UnexpectedTokenException("Expected PatchSect token but got 0x" + fileHeader.EndToken.ToString("X8")); } // file searches? List <PatchSearch> searchSegments = new List <PatchSearch>(); while (true) { bool isPresent = (StreamTools.ReadInt32(buffer, ref offset) != 0); if (!isPresent) { break; } int characterCount = StreamTools.ReadInt32(buffer, ref offset); PatchSearch searchSegment = new PatchSearch { IsPresent = true, CharacterCount = characterCount, FileSearch = StreamTools.ReadStringUnicode(buffer, ref offset, characterCount, false) }; searchSegments.Add(searchSegment); } // files List <PatchEntryStruct> entries = new List <PatchEntryStruct>(); while (true) { int characterCount = StreamTools.ReadInt32(buffer, ref offset); PatchEntryStruct entrySegment = new PatchEntryStruct { CharacterCount = characterCount, FileName = StreamTools.ReadStringUnicode(buffer, ref offset, characterCount, false), UsedInX86 = (StreamTools.ReadInt32(buffer, ref offset) != 0), UsedInX64 = (StreamTools.ReadInt32(buffer, ref offset) != 0), Localization = StreamTools.ReadInt16(buffer, ref offset), FileSize = StreamTools.ReadInt64(buffer, ref offset), DatOffset = StreamTools.ReadInt64(buffer, ref offset), Hash = StreamTools.ReadInt32(buffer, ref offset), HasMoreEntries = StreamTools.ReadInt32(buffer, ref offset), }; entries.Add(entrySegment); if (entrySegment.HasMoreEntries == -1) { break; } } // add files to file list (could be done in above loop, but as mentioned earlier, this parsing method is almost enitrely out of random interest foreach (PatchEntryStruct entry in entries) { PackFileEntry fileEntry = new PatchFileEntry(entry) { Pack = this }; Files.Add(fileEntry); } HasIntegrity = (offset == buffer.Length); }
public override sealed bool ParseData(byte[] buffer) { if ((buffer == null)) { return(false); } int offset = 0; StringsHeader stringsHeader = FileTools.ByteArrayToStructure <StringsHeader>(buffer, ref offset); for (int i = 0; i < stringsHeader.Count; i++) { StringBlock stringBlock = new StringBlock { ReferenceId = FileTools.ByteArrayToInt32(buffer, ref offset), Unknown = FileTools.ByteArrayToInt32(buffer, ref offset) }; int count = FileTools.ByteArrayToInt32(buffer, ref offset); stringBlock.StringId = FileTools.ByteArrayToStringASCII(buffer, offset); offset += count + 1; stringBlock.Reserved = FileTools.ByteArrayToInt32(buffer, ref offset); count = FileTools.ByteArrayToInt32(buffer, ref offset); stringBlock.String = FileTools.ByteArrayToStringUnicode(buffer, offset, count); offset += count; int attributeCount = FileTools.ByteArrayToInt32(buffer, ref offset); for (int j = 0; j < attributeCount; j++) { count = FileTools.ByteArrayToInt32(buffer, ref offset); int byteCount = (count + 1) * 2; switch (j) { case 0: stringBlock.Attribute1 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount); break; case 1: stringBlock.Attribute2 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount); break; case 2: stringBlock.Attribute3 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount); break; case 3: stringBlock.Attribute4 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount); break; } offset += byteCount; } Rows.Add(stringBlock); } return(HasIntegrity = ((offset == buffer.Length)) ? true : false); }