Пример #1
0
        /// <summary>
        /// Parses a GW2 string file.
        /// </summary>
        /// <param name="file">Raw string file extracted from GW2.dat or Local.dat</param>
        /// <param name="timestamp">Mark entries with custom timestamp</param>
        /// <returns>Number of strings in collection</returns>
        public int Read(string file, DateTime timestamp)
        {
            Items.Clear();
            Filename = Path.GetFileName(file);

            // Open the string file.
            byte[] fileBuffer = System.IO.File.ReadAllBytes(file);

            // Byte 00 + 01 = string length
            // Byte 04      = string type
            byte[] header = new byte[6];
            byte[] strs   = new byte[4];

            // Start reading after strs
            long position = 4;

            // Stores blocksize
            long blocksize = 0;

            // Stores row number in file
            int row = 0;

            // Make sure your file is at least 6 bytes
            if (fileBuffer.Length > 6)
            {
                Array.Copy(fileBuffer, 0, strs, 0, 4);

                // Check FourCC and make sure the file uses a valid language
                if (fileBuffer[fileBuffer.Length - 2] < 5 && FourCC.SequenceEqual(strs))
                {
                    // Set language
                    Language = (GW2Language)fileBuffer[fileBuffer.Length - 2];

                    // Keep reading the file, we don't need the last 2 language bytes.
                    while (position < fileBuffer.Length - 2)
                    {
                        // Create a new entry
                        GW2Entry entry = new GW2Entry();
                        entry.row   = row;
                        entry.stamp = timestamp;

                        // Read block header
                        Array.Copy(fileBuffer, position, header, 0, 6);
                        position += 6;

                        // Get the string size
                        blocksize = header[0] + (header[1] * 256) - 6;

                        if (blocksize <= 0)
                        {
                            // Empty block
                            entry.type  = GW2EntryType.Empty;
                            entry.value = string.Empty;
                        }
                        else
                        {
                            // Read the block
                            if (header[4] == 16)
                            {
                                // UTF-16 String
                                entry.value = Encoding.Unicode.GetString(fileBuffer, (int)position, (int)blocksize);
                                entry.type  = GW2EntryType.String;
                            }
                            else
                            {
                                // Other String
                                entry.type = GW2EntryType.Other;
                            }

                            // Moving on...
                            position += blocksize;
                        }

                        // Add entry
                        // NOTE: I've only set it to store actual strings to save all types change this line to:
                        //
                        //      Items.Add(entry);
                        //
                        if (entry.type == GW2EntryType.String)
                        {
                            Items.Add(entry);
                        }

                        // Next row
                        row++;
                    }
                }
            }

            fileBuffer = null;

            // Done!
            return(Items.Count);
        }
Пример #2
0
        /// <summary>
        /// Parses a GW2 string file.
        /// </summary>
        /// <param name="file">Raw string file extracted from GW2.dat or Local.dat</param>
        /// <param name="timestamp">Mark entries with custom timestamp</param>
        /// <returns>Number of strings in collection</returns>
        public int Read(string file, DateTime timestamp)
        {
            Items.Clear();
            Filename = Path.GetFileName(file);

            // Open the string file.
            byte[] fileBuffer = System.IO.File.ReadAllBytes(file);

            // Byte 00 + 01 = string length
            // Byte 04      = string type
            byte[] header = new byte[6];
            byte[] strs = new byte[4];

            // Start reading after strs
            long position = 4;

            // Stores blocksize
            long blocksize = 0;

            // Stores row number in file
            int row = 0;

            // Make sure your file is at least 6 bytes
            if (fileBuffer.Length > 6)
            {
                Array.Copy(fileBuffer, 0, strs, 0, 4);

                // Check FourCC and make sure the file uses a valid language
                if (fileBuffer[fileBuffer.Length - 2] < 5 && FourCC.SequenceEqual(strs))
                {
                    // Set language
                    Language = (GW2Language) fileBuffer[fileBuffer.Length - 2];

                    // Keep reading the file, we don't need the last 2 language bytes.
                    while (position < fileBuffer.Length - 2)
                    {
                        // Create a new entry
                        GW2Entry entry = new GW2Entry();
                        entry.row = row;
                        entry.stamp = timestamp;

                        // Read block header
                        Array.Copy(fileBuffer, position, header, 0, 6);
                        position += 6;

                        // Get the string size
                        blocksize = header[0] + (header[1] * 256) - 6;
                        
                        if (blocksize <= 0)
                        {
                            // Empty block
                            entry.type = GW2EntryType.Empty;
                            entry.value = string.Empty;
                        }
                        else
                        {
                            // Read the block
                            if (header[4] == 16)
                            {
                                // UTF-16 String
                                entry.value = Encoding.Unicode.GetString(fileBuffer, (int)position, (int)blocksize);
                                entry.type = GW2EntryType.String;
                            }
                            else
                            {
                                // Other String
                                entry.type = GW2EntryType.Other;
                            }

                            // Moving on...
                            position += blocksize;
                        }

                        // Add entry
                        // NOTE: I've only set it to store actual strings to save all types change this line to:
                        //
                        //      Items.Add(entry);
                        //
                        if (entry.type == GW2EntryType.String) Items.Add(entry);

                        // Next row
                        row++;
                    }
                }
            }

            fileBuffer = null;

            // Done!
            return Items.Count;
        }