/// <summary> /// Decodes the ARZ file. /// </summary> /// <param name="inReader">input BinaryReader</param> /// <param name="baseOffset">Offset in the file.</param> /// <param name="arzFile">ArzFile instance which we are operating.</param> public void Decode(BinaryReader inReader, int baseOffset, ArzFile arzFile) { // Record Entry Format // 0x0000 int32 stringEntryID (dbr filename) // 0x0004 int32 string length // 0x0008 string (record type) // 0x00?? int32 offset // 0x00?? int32 length in bytes // 0x00?? int32 timestamp? // 0x00?? int32 timestamp? this.idStringIndex = inReader.ReadInt32(); this.RecordType = TQData.ReadCString(inReader); this.offset = inReader.ReadInt32() + baseOffset; // Compressed size // We throw it away and just advance the offset in the file. inReader.ReadInt32(); // Crap1 - timestamp? // We throw it away and just advance the offset in the file. inReader.ReadInt32(); // Crap2 - timestamp? // We throw it away and just advance the offset in the file. inReader.ReadInt32(); // Get the ID string this.ID = arzFile.Getstring(this.idStringIndex); }
/// <summary> /// Reads the whole string table into memory from a stream. /// </summary> /// <remarks> /// string Table Format /// first 4 bytes is the number of entries /// then /// one string followed by another... /// </remarks> /// <param name="pos">position within the file.</param> /// <param name="reader">input BinaryReader</param> /// <param name="outStream">output StreamWriter.</param> private void ReadStringTable(int pos, BinaryReader reader, StreamWriter outStream) { reader.BaseStream.Seek(pos, SeekOrigin.Begin); int numstrings = reader.ReadInt32(); this.strings = new string[numstrings]; if (outStream != null) { outStream.WriteLine("stringTable located at 0x{1:X} numstrings= {0:n0}", numstrings, pos); } for (int i = 0; i < numstrings; ++i) { this.strings[i] = TQData.ReadCString(reader); if (outStream != null) { outStream.WriteLine("{0},{1}", i, this.strings[i]); } } }
/// <summary> /// Parses the raw binary data for use within TQVault /// </summary> private void ParseRawData() { // First create a memory stream so we can decode the binary data as needed. using (MemoryStream stream = new MemoryStream(this.rawData, false)) { using (BinaryReader reader = new BinaryReader(stream)) { // Find the block pairs until we find the block that contains the item data. int blockNestLevel = 0; int currentOffset = 0; int itemOffset = 0; int equipmentOffset = 0; // vaults start at the item data with no crap bool foundItems = this.IsVault; bool foundEquipment = this.IsVault; while ((!foundItems || !foundEquipment) && (currentOffset = this.FindNextBlockDelim(currentOffset)) != -1) { if (this.rawData[currentOffset] == beginBlockPattern[0]) { // begin block ++blockNestLevel; currentOffset += beginBlockPattern.Length; // skip past the 4 bytes of noise after begin_block currentOffset += 4; // Seek our stream to the correct position stream.Seek(currentOffset, SeekOrigin.Begin); // Now get the string for this block string blockName = TQData.ReadCString(reader).ToUpperInvariant(); // Assign loc to our new stream position currentOffset = (int)stream.Position; // See if we accidentally got a begin_block or end_block if (blockName.Equals("BEGIN_BLOCK")) { blockName = "(NONAME)"; currentOffset -= beginBlockPattern.Length; } else if (blockName.Equals("END_BLOCK")) { blockName = "(NONAME)"; currentOffset -= endBlockPattern.Length; } else if (blockName.Equals("ITEMPOSITIONSSAVEDASGRIDCOORDS")) { currentOffset += 4; itemOffset = currentOffset; // skip value for itemPositionsSavedAsGridCoords foundItems = true; } else if (blockName.Equals("USEALTERNATE")) { currentOffset += 4; equipmentOffset = currentOffset; // skip value for useAlternate foundEquipment = true; } // Print the string with a nesting level indicator ////string levelString = new string ('-', System.Math.Max(0,blockNestLevel*2-2)); ////out.WriteLine ("{0} {2:n0} '{1}'", levelString, blockName, loc); } else { // end block --blockNestLevel; currentOffset += endBlockPattern.Length; ////if (blockNestLevel < 0) ////{ //// out.WriteLine ("{0:n0} Block Nest Level < 0!!!", loc); ////} } } ////out.WriteLine ("Final Block Level = {0:n0}", blockNestLevel); if (foundItems) { try { this.ParseItemBlock(itemOffset, reader); } catch (ArgumentException exception) { if (!TQDebug.DebugEnabled) { TQDebug.DebugEnabled = true; } TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error parsing player file Item Block - '{0}'", this.PlayerName)); TQDebug.DebugWriteLine(exception.ToString()); throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error parsing player file Item Block- '{0}'", this.PlayerName), exception); } try { string outfile = string.Concat(Path.Combine(TQData.TQVaultSaveFolder, this.PlayerName), " Export.txt"); using (StreamWriter outStream = new StreamWriter(outfile, false)) { outStream.WriteLine("Number of Sacks = {0}", this.numberOfSacks); int sackNumber = 0; foreach (SackCollection sack in this.sacks) { if (!sack.IsEmpty) { outStream.WriteLine(); outStream.WriteLine("SACK {0}", sackNumber); int itemNumber = 0; foreach (Item item in sack) { object[] params1 = new object[20]; params1[0] = itemNumber; params1[1] = item.ToString(); params1[2] = item.PositionX; params1[3] = item.PositionY; params1[4] = item.Seed; ////params1[5] = outStream.WriteLine(" {0,5:n0} {1}", params1); itemNumber++; } } sackNumber++; } } } catch (IOException exception) { if (!TQDebug.DebugEnabled) { TQDebug.DebugEnabled = true; } TQDebug.DebugWriteLine(string.Format( CultureInfo.InvariantCulture, "Error writing Export file - '{0}'", string.Concat(Path.Combine(TQData.TQVaultSaveFolder, this.PlayerName), " Export.txt"))); TQDebug.DebugWriteLine(exception.ToString()); } } // Process the equipment block if (foundEquipment && !this.IsVault) { try { this.ParseEquipmentBlock(equipmentOffset, reader); } catch (ArgumentException exception) { if (!TQDebug.DebugEnabled) { TQDebug.DebugEnabled = true; } TQDebug.DebugWriteLine(string.Format(CultureInfo.InvariantCulture, "Error parsing player file Equipment Block - '{0}'", this.PlayerName)); TQDebug.DebugWriteLine(exception.ToString()); throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Error parsing player file Equipment Block - '{0}'", this.PlayerName), exception); } try { string outfile = string.Concat(Path.Combine(TQData.TQVaultSaveFolder, this.PlayerName), " Equipment Export.txt"); using (StreamWriter outStream = new StreamWriter(outfile, false)) { if (!this.EquipmentSack.IsEmpty) { int itemNumber = 0; foreach (Item item in this.EquipmentSack) { object[] params1 = new object[20]; params1[0] = itemNumber; params1[1] = item.ToString(); params1[2] = item.PositionX; params1[3] = item.PositionY; params1[4] = item.Seed; ////params1[5] = outStream.WriteLine(" {0,5:n0} {1}", params1); itemNumber++; } } } } catch (IOException exception) { if (!TQDebug.DebugEnabled) { TQDebug.DebugEnabled = true; } TQDebug.DebugWriteLine(string.Format( CultureInfo.InvariantCulture, "Error writing Export file - '{0}'", string.Concat(Path.Combine(TQData.TQVaultSaveFolder, this.PlayerName), " Equipment Export.txt"))); TQDebug.DebugWriteLine(exception.ToString()); } } } } }